Compare commits

...
973 Commits
Author SHA1 Message Date
Connor McLaughlinandlightningterror 749f225562 FullscreenUI: Use spinboxes for crop 2022-12-20 13:34:40 +01:00
Comfarolandlightningterror 2e065b128a GunCon2: Add screen parameters for more games
PAL versions of Endgame, Vampire Night adjustment, Guncom 2, Virtua Cop
2022-12-20 07:03:16 +01:00
PCSX2 Botandlightningterror d60ae20839 PAD: Update to latest controller database. 2022-12-19 17:55:24 +01:00
ComfarolandGitHub 441b23bce5 GunCon2: Add screen parameters for more games (#7627) 2022-12-19 15:42:35 +00:00
Ziemasandrefractionpcsx2 44c01dd73e qusb: missing <cstdint> & <cstddef> include 2022-12-19 15:41:07 +00:00
Ziemasandrefractionpcsx2 01ca4e25ae usb-eyetoy: missing <memory> include 2022-12-19 15:41:07 +00:00
Ziemasandrefractionpcsx2 3c39a9ab22 StateWrapper: Add missing <array> include 2022-12-19 15:41:07 +00:00
RedDevilusandrefractionpcsx2 74808095b9 GameDB: Wild ARMs 3,4,5,F + maintenance
Reduces Hash cache numbers, improving speed in certain areas and reduces GS usage.

An oddity is that it is less effective on 5 and also needs roundsprite half and not Wild arms. I wonder if they made big changes in the engine compared to 3 and 4.

I also fixed the discrepancies between regions (missing fixes probably missed due to having different naming for the Japanese versions)

As well as fixing comments + missing serials
2022-12-19 15:40:42 +00:00
Connor McLaughlinandrefractionpcsx2 09f2d4f546 GS/DX12: Fix incorrect sampler being used in utility draws 2022-12-19 15:38:59 +00:00
Stuart Kennyandrefractionpcsx2 1480d9ac20 USB: Add deadzone for USB wheel steering axis 2022-12-19 13:41:08 +00:00
lightningterror c00c125191 Revert "USB: Buzz Button reorder"
This reverts commit 7ac0e38f35.

This was actually wrong, there's a correct way to go about it.
2022-12-19 03:28:43 +01:00
Simonxddandlightningterror 7ac0e38f35 USB: Buzz Button reorder
reordered Buttons to be more intuitive
2022-12-18 23:52:15 +01:00
Mrlinkwiiandrefractionpcsx2 59b870d3dc GameDB: Add autoFlush to Syphon Filter - The Omega Strain 2022-12-18 20:26:33 +00:00
Connor McLaughlinandrefractionpcsx2 d2dd796cb9 USB: Add missing extra controller bindings for Buzz 2022-12-18 16:24:30 +00:00
JordanTheToasterandrefractionpcsx2 ccadf5d09c GameDB: Add missing Energy Airforce entry's
Adds missing entry's for energy airforce
2022-12-18 16:08:46 +00:00
Connor McLaughlinandlightningterror dbe078c8b3 GunCon2: Add values for TC2/3 PAL
Courtesy of Codeine.
2022-12-18 14:54:21 +01:00
Connor McLaughlinandlightningterror 129bc0819b InputManager: Input subclass needs 3 bits now 2022-12-18 14:54:21 +01:00
Connor McLaughlinandlightningterror 3f5dc4e182 GunCon2: Max value for scale X/Y should be 200 not 100 2022-12-18 14:54:21 +01:00
arcum42andrefractionpcsx2 4de0fbe6b0 USB: Don't register the device if the DeviceType is none. 2022-12-18 09:00:25 +00:00
arcum42andrefractionpcsx2 c46d316e95 USB: Don't crash and burn if there is no ini file for pcsx2. 2022-12-18 09:00:25 +00:00
TellowKrinkleandrefractionpcsx2 8cf430ef7e SDLInputSource: Custom hint support 2022-12-18 08:27:07 +00:00
TellowKrinkleandrefractionpcsx2 e2c3a8b1e1 SettingsInterface: Add Key+Value setting support 2022-12-18 08:27:07 +00:00
TellowKrinkleandrefractionpcsx2 1b50fb982a LayeredSettingsInterface: Simplify checked unwraps 2022-12-18 08:27:07 +00:00
TellowKrinkleandrefractionpcsx2 ff4c741f4b Input:SDL: Add more hints 2022-12-18 08:27:07 +00:00
TellowKrinkleandrefractionpcsx2 1a015089ed wxSettingsInterface: Formatting 2022-12-18 08:27:07 +00:00
TellowKrinkleandrefractionpcsx2 ef70aa410e Updater: Properly display error messages 2022-12-18 07:56:03 +00:00
TellowKrinkleandrefractionpcsx2 636e0de5aa Updater: Disable updater for tags that don't look like official releases 2022-12-18 07:56:03 +00:00
TellowKrinkleandrefractionpcsx2 8925da94e1 Updater: MacOS support 2022-12-18 07:56:03 +00:00
TellowKrinkleandrefractionpcsx2 d7ef8a48fe Updater: Use ifdef for multi isa check
if worked fine but it really should be ifdef
2022-12-18 07:56:03 +00:00
TellowKrinkleandrefractionpcsx2 bf32cdd683 Updater: Formatting 2022-12-18 07:56:03 +00:00
Connor McLaughlinandrefractionpcsx2 6b3a8066e3 cmake: Remove PulseAudio dependency
Also no longer needed.
2022-12-18 04:24:04 +00:00
Connor McLaughlinandrefractionpcsx2 fddef65a58 3rdparty: Remove libsamplerate
Since we're using cubeb for USB audio emulation, libsamplerate is no
longer needed as cubeb has its own resampler.
2022-12-18 04:24:04 +00:00
Connor McLaughlinandrefractionpcsx2 9388c483ec InputManager: Support for inverted bindings (i.e. pedals) 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 7cbede9190 USB: Remove IO vector for packets
It was unnecessary as our packets were always contiguous, and also GPL
instead of LGPL.
2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 fc14b8f0da USB: Move to Qt (with *significant* refactoring) 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 4ebb5a87b2 SDLInputSource: Support joysticks as well as controllers 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 8dba6a186f Config: Add dynamic options to SettingInfo 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 b1ff979171 Misc: Add StateWrapper
Eventually we'll move save states over to it..
2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 ebeb88d425 Common: Add HeapArray 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 d7c7aa2215 InputManager: Move GenericInputBinding to core 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 6f407b2080 PAD: Add bind index to InputBindingInfo 2022-12-18 03:47:00 +00:00
Connor McLaughlinandrefractionpcsx2 59e10bcac6 PAD: Move input-related stuff out 2022-12-18 03:47:00 +00:00
Connor McLaughlinandlightningterror 256f7b9b0f OpenGLHostDisplay: Fix incorrect EndQuery() on shutdown 2022-12-17 11:40:06 +01:00
Connor McLaughlinandlightningterror f2ca07033c GS/OpenGL: Fix texture uploads in big picture mode 2022-12-17 11:40:06 +01:00
lightningterror e233f1dded GS-ogl: Remove extra DSA log.
There is already a log that checks the extension itself.
2022-12-17 02:49:29 +01:00
lightningterror 07c09f255d GS: Move osd log for unsupported cas in Renderer code. 2022-12-16 18:32:57 +01:00
lightningterror 774d0326c7 GS-d3d11: Fix dx11 bad shader/crashing on dx10 gpus.
CAS requires feature level 11.0.
2022-12-16 18:32:57 +01:00
Connor McLaughlinandrefractionpcsx2 ce412686b9 VMManager: Better separate shutdown and close for SPU2 and GS 2022-12-16 11:51:26 +00:00
Connor McLaughlinandrefractionpcsx2 dfcf9fa6aa ImGuiManager: Log OSD messages when they're added 2022-12-16 11:15:42 +00:00
Connor McLaughlinandrefractionpcsx2 6a548440ea D3D12/Context: Don't assert-fail when D3D12 is unavailable 2022-12-16 11:11:36 +00:00
Connor McLaughlinandrefractionpcsx2 eba2273cd1 GS/OpenGL: Cleanups and GLES support 2022-12-16 11:11:15 +00:00
lightningterror 3f1fb1fc3c GS-d3d12: Fix command buffer log. 2022-12-16 11:34:17 +01:00
lightningterror 35cbfb3fb0 wx: Fix console warnings for no longer used hotkeys.
Fixes Kbd Accelerator warnings on pcsx2 console.
2022-12-16 11:19:19 +01:00
RedDevilusandrefractionpcsx2 6bf8f43ab1 GameDB: Black line removal K-1 World Grand Prix
Align Sprite needed, surprised this one wasn't discovered before.
2022-12-16 10:05:36 +00:00
TellowKrinkleandrefractionpcsx2 3204b98aaf microVU: Fix mVUcustomSearch
Apparently NOT doesn't set flags
2022-12-16 08:18:49 +00:00
refractionpcsx2 f29c2a5805 GameDB: Add upscaling fix for Violet no Atelier 2022-12-15 10:04:48 +00:00
Connor McLaughlinandlightningterror facbfa479b Qt: Fix graphics settings opening to replacement tab 2022-12-14 12:50:30 +01:00
refractionpcsx2 555b8efcad GSRunner: Fix compilation 2022-12-13 20:57:55 +00:00
Mrlinkwiiandrefractionpcsx2 0e268864e2 GameDB : add EE Nearest Rounding to Blood Omen 2 2022-12-13 19:10:29 +00:00
refractionpcsx2 a7687947e6 GS: Fix crash if FXAA/Shadeboost enabled with Bilinear Sharp 2022-12-13 01:21:29 +00:00
PCSX2 Botandlightningterror 8254ff078e PAD: Update to latest controller database. 2022-12-12 23:53:55 +01:00
refractionpcsx2 f8d90d68a3 GameDB: Add mipmapping fixes for Monster Attack/Chikyuu Boueigun 2022-12-12 20:49:03 +00:00
Connor McLaughlinandrefractionpcsx2 60fe05bc63 Qt: Fix crash opening ELF game properties
Introduced in 9da8e9280f
2022-12-12 14:46:49 +00:00
Connor McLaughlinandrefractionpcsx2 fa2db10e44 GSRunner: Kick screenshots on the GS thread
Instead of from the "CPU" thread.
2022-12-12 14:34:22 +00:00
Connor McLaughlinandrefractionpcsx2 06081ca18b GSDumpReplayer: Fix frame advancing
It would always advance by two frames before.
2022-12-12 14:34:22 +00:00
Connor McLaughlinandrefractionpcsx2 34fad0bf98 GS: Ensure screenshots are saved before shutting down 2022-12-12 14:34:22 +00:00
AKuHAKandrefractionpcsx2 78ad2cfb88 CDVD: set default region data for PStwo nvram, set iLink ID checksum for bios v1.70 and up 2022-12-12 13:38:42 +00:00
Connor McLaughlinandrefractionpcsx2 9da8e9280f Qt: Add disc path option for ELF game list entries 2022-12-12 13:35:37 +00:00
IlDucciandrefractionpcsx2 8ac0bd452e GameDB: PAL localized names fixes
What began as a proofread/revision of all PAL-S discs ended up touching a bit more than I thought, adding the proper names for also other French/Italian/German exclusive versions.

Summary of changes:
 - Verified EVERY PAL-S disc's name and uppercasing following whatever is written on the cover's side.
 - Added the proper translations for French/German/Italian versions of the discs I have changed in their Spanish equivalents. For these cases, I first took the name from Wikipedia and then verified it by searching good photos of the cover sides on eBay. I was able to double check the wordings and accents (I'm looking at you, German Wikipedia and the Lord of The Rings games...), but not the actual uppercasing for all of these versions, so some of those have the uppercasing from Wikipedia.
- When I checked Terminator 3 - Rise of the Machines's Spanish version, I found out that the disc seems to be Italian/Spanish, so I changed that accordingly. Reference: https://www.ebay.es/itm/192542047505?hash=item2cd4667d11:g:420AAOSwJX5f9EXg&amdata=enc%3AAQAHAAAA4EfM99%2Bn1tQrgxNjriGyyACKNUHzF1eA2G3W4Ig9NuggC280vKaD5O0lG8xWUDOAS6vaXepjpLFpv0REdj8r5lGdiIUs4OFD6s65%2FH0vSC%2Bb7X%2F%2BmsfEyUGhuvJEXEFQC96lDHkyyOqkQabmyM%2Bj881BRmGiUzDorYRZWnHhAOEDWSmErI8oyK%2F0U5eCOF3vPF8bDZaFO54eJ7VjO0UcDmniSvyWUq7lOIiFhEgFeGeZIKIW%2BLPcQMGGZ7oUT5AmNis2aluj2Wg6rOSAQaie1fe7zf6%2FkJ5Db%2BDrfB6vsp31%7Ctkp%3ABk9SR_bDyeOgYQ
 - I've removed a mistype for Over the Hedge's Spanish version, as it was duped: I do not know what SLES-53897 contains, but the actual game seems to be SLES-53987.
2022-12-12 12:22:53 +00:00
Connor McLaughlinandrefractionpcsx2 98038201b3 GS: Always allocate wrapped local memory
Simplifies things since we don't need to care about <Win10 support now.

Also gets rid of vmalloc() in favor of the common routines.
2022-12-12 11:54:25 +00:00
JordanTheToasterandrefractionpcsx2 62b1688856 GameDB: Game and name fixes
Fixes white lines in Drakengard using merge sprite and fixes the name of the Spanish monsters inc scare island and Buzz!.
2022-12-12 09:32:20 +00:00
refractionpcsx2 2dd9741102 GameDB: Remove wrapgsmem entries from gamedb 2022-12-12 09:31:26 +00:00
refractionpcsx2 6d5c05fba3 GS: Enable memory wrapping always 2022-12-12 09:31:26 +00:00
Connor McLaughlinandrefractionpcsx2 d93b49cc4f GS: Use point sampling for shadeboost
DX12/Vulkan already did, but DX11/GL used linear.
2022-12-12 09:31:11 +00:00
Connor McLaughlinandrefractionpcsx2 6ccb55d6f7 GS: Remove additional copy in FXAA/ShadeBoost 2022-12-12 09:31:11 +00:00
Connor McLaughlinandrefractionpcsx2 a1fb735fde GS/DX12: Ensure utility root signature is set before constants
Fixes a validation error when using shade boost.
2022-12-12 09:31:11 +00:00
Connor McLaughlinandrefractionpcsx2 066cf42338 GS: Compute luminance in shader for FXAA
Fixes FXAA being broken after b706c25b68.

Will be slightly difference since this is using the BT.709 coefficients
instead of CCIR 601 - but it matches the non-gather codepath now.
2022-12-12 09:31:11 +00:00
KrossXandrefractionpcsx2 5c952fbbd6 GS: Preserve deinterlacing render target when Shadeboost or FXAA are
enabled.
2022-12-11 19:07:38 +00:00
escape209andlightningterror 60b92ba775 Qt: Fix being able to access hidden tabs in Graphics menu 2022-12-11 16:02:55 +01:00
refractionpcsx2 1242f6c942 GS-SW: Don't anti-blur frame rect when same source and not anti-bluring 2022-12-11 06:41:48 +00:00
Connor McLaughlinandrefractionpcsx2 1920bff007 x86/iR5900: Fix msub.s/madd.s when ACC isn't live
Don't read EEREC_nnn without checking the process/valid bit first.
2022-12-11 05:43:49 +00:00
Connor McLaughlinandrefractionpcsx2 05c12e2505 x86/iR5900: Don't flush regcache for store logging
Makes it a bit easier to debug register cache issues.
2022-12-11 05:43:49 +00:00
Connor McLaughlinandrefractionpcsx2 354951f1d6 GS: Add internal resolution screenshot option 2022-12-11 03:00:49 +00:00
Connor McLaughlinandrefractionpcsx2 a67d3e9aee GS: Remove Zoom and Offsets
Crop is far superior since it operates at pixel increments, and lets
you control all four edges independently.
2022-12-11 03:00:49 +00:00
Connor McLaughlinandrefractionpcsx2 b706c25b68 GS: Change transparency shader to output full alpha 2022-12-11 03:00:49 +00:00
Mrlinkwiiandrefractionpcsx2 4dbe17eaf9 GameDB: add VUclamping to 'NHL 2004' 2022-12-11 00:30:58 +00:00
TellowKrinkleandrefractionpcsx2 a4b598aa15 Updater: Preserve non-standard exe names on update 2022-12-10 20:06:05 +00:00
TellowKrinkleandrefractionpcsx2 05a9a71f4a Updater: Support multi-isa switchover 2022-12-10 20:06:05 +00:00
Mrlinkwiiandrefractionpcsx2 9b2caa6fdd GameDB : add fixes to 'Conspiracy - Weapons of Mass Destruction' 2022-12-08 18:32:09 +00:00
lightningterror bebb748546 wx: Rename some options to match recent Qt changes.
TV Shader drop down list:
None -> None (Default)

Sharpening drop down list:
Disabled -> None (Default)

Renderer Automatic -> Automatic (Default)
2022-12-08 19:18:20 +01:00
lightningterror b509a849a1 Qt: Add tooltips to Audio settings.
Only option name and default setting, no actual tooltip.
2022-12-08 19:18:20 +01:00
lightningterror 20602650c4 FullscreenUI: Rename some options.
TV Shader drop down list:
None -> None (Default)

Sharpening drop down list:
Disabled -> None (Default)

Renderer Automatic -> Automatic (Default)
2022-12-08 19:18:20 +01:00
lightningterror a2d0b8b452 Qt: Add tooltips to Advanced settings. 2022-12-08 19:18:20 +01:00
lightningterror 1fa7526036 Qt: Properly disable Skipdraw global on release builds. 2022-12-08 19:18:20 +01:00
lightningterror 1033726d65 Qt: Rename some options.
TV Shader drop down list:
None -> None (Default)

Sharpening drop down list:
Disabled -> None (Default)

Renderer Automatic -> Automatic (Default)
2022-12-08 19:18:20 +01:00
lightningterror e5c3f82dd9 Qt: Add tooltips to Graphics settings.
Most of them are only default settings for the options.
2022-12-08 19:18:20 +01:00
lightningterror 2c21dddea9 Qt: Add tooltips to Interface settings.
Tooltips itself are empty, just add the default checked value.
2022-12-08 19:18:20 +01:00
RedDevilusandrefractionpcsx2 208812347f Qt: Resizes + better tooltips + Savestate warning
Bigger tooltip window
Controllers button shows up correctly at different DPI percentages
Rename some options
2022-12-08 16:06:31 +00:00
Mrlinkwiiandrefractionpcsx2 8c8a8f9994 GameDB: add missing Arcana Heart 2 serial 2022-12-08 16:05:05 +00:00
Connor McLaughlinandrefractionpcsx2 77e9938f0f GS: Manually throttle fullscreen UI rendering
Fixes rendering at thousands of FPS when pausing if FSUI is active.

Avoids flickering when recreating swap chain in vulkan on menu open,
because we're no longer doing it.
2022-12-08 09:36:41 +00:00
Connor McLaughlinandrefractionpcsx2 aea6a9f534 Common: Add Threading::SleepUntil() 2022-12-08 09:36:41 +00:00
TellowKrinkleandTellowKrinkle a346cff472 CMake: Fix issues with linkers failing on Linux 2022-12-07 22:31:33 -06:00
Connor McLaughlinandrefractionpcsx2 1b3c3efcd5 Achievements: Add option to disable notifications 2022-12-07 00:25:13 +00:00
Connor McLaughlinandrefractionpcsx2 898055a3c2 GS/HW: Don't consider custom textures in hash cache overflow
Prevents hash cache from being disabled due to a large number of custom
textures. The VRAM usage from the custom textures will still be shown in
the OSD.
2022-12-07 00:24:51 +00:00
JordanTheToasterandrefractionpcsx2 f2030d9957 GameDB: A few game fixes and tweaks
HPO Normal causes really bad glitching on the floor in KH2 round sprite breaks light bloom in Price of Persia WW and WRC Rally Evolved needs round sprite half to fix misaligned text.
2022-12-06 16:36:35 +00:00
Connor McLaughlinandrefractionpcsx2 a5f323e4e3 GS: Add missing initialization of m_skipped_duplicate_frames 2022-12-06 13:04:12 +00:00
lightningterror bdb1fd517b gui-wx: Fix OsdShowFrameTimes default config. 2022-12-05 23:00:33 +01:00
PCSX2 Botandlightningterror 6ce75453fe PAD: Update to latest controller database. 2022-12-05 22:35:13 +01:00
lightningterror 80aed98e97 Qt: Add tooltips to memcard checkbox options. 2022-12-05 06:49:38 +01:00
Connor McLaughlinandlightningterror 7e939b7535 SaveState: Bump version
[SAVEVERSION+] 44e69a9 changed the size of the microVU state struct, which is saved
(to resume incomplete micros), without bumping the version.
2022-12-05 04:07:15 +01:00
JordanTheToasterandrefractionpcsx2 57f0ebbff9 GameDB: Add comment for Mipmapping on P3 FES
Adds a comment to the game fix on P3 Fes to mention the flashing windows it fixes.
2022-12-04 23:42:25 +00:00
lightningterror a426df9c65 Qt: Correct bilinear default option tooltip.
Close #7538
2022-12-04 23:10:09 +01:00
Connor McLaughlinandrefractionpcsx2 2584835176 CMake: Drop SPU2X_PULSEAUDIO define 2022-12-04 20:56:48 +00:00
refractionpcsx2 40cb41399f VU: Correct XGKick timing when using XGKickSync 2022-12-04 19:44:15 +00:00
Mrlinkwiiandrefractionpcsx2 eedea5cbf7 GameDB : add AdaptiveBFF to 'K-1 World Grand Prix 2006' and 'Elemental Gerad' 2022-12-04 16:28:39 +00:00
Connor McLaughlinandrefractionpcsx2 bd97a7a216 FullscreenUI: Allow unbinding a hotkey/controller with Triangle
Previously this wasn't possible with a controller, only the mouse.

Follow the same convention as other UI options (alternate action =
triangle/Y).
2022-12-04 14:33:23 +00:00
Connor McLaughlinandrefractionpcsx2 d1891fc31c Qt: Remove hardware download mode from global settings
Previously it would be disabled, leading to user confusion.
2022-12-04 14:33:00 +00:00
Connor McLaughlinandlightningterror 20193eae36 Qt: Remove dead code from ControllerBindingWidget_Base
This was moved to the settings tab a while back.
2022-12-04 11:37:54 +01:00
Connor McLaughlinandrefractionpcsx2 1cb10eb889 FullscreenUI: Don't clear state when switching renderers
Fixes things like the achievement summary not being displayed, or if the
pause menu is never accessed, the popups from showing at all.
2022-12-04 04:27:38 +00:00
Connor McLaughlinandrefractionpcsx2 d52352966e InputManager: Add IsInputSourceEnabled 2022-12-04 04:27:38 +00:00
TellowKrinkleandTellowKrinkle a8382ceb50 GHActions: Switch linux release pipeline to full lto
Missed that last time
2022-12-03 14:42:22 -06:00
TellowKrinkleandTellowKrinkle d47c9b0773 CMake: Fix LTO_PCSX2_CORE + DISABLE_ADVANCE_SIMD 2022-12-03 14:42:22 -06:00
TellowKrinkleandTellowKrinkle 1a383de5c4 IPU: MultiISA IPU 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 44e69a9603 microVU: Adjust microRegInfo to match size of mVUCustomSearch 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 91cba0ec45 microVU: Fix up mVUCustomSearch
Fixes SSE4 version to follow WIN32 x86-64 calling convention (don't clobber xmm6 or xmm7)
Fixes AVX version to properly include fourth ymm register in result
2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle e0a0e0b00c microVU: Choose AVX2/SSE at runtime 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 22f214c8e1 GHActions: Check multi-isa builds for global constructors 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 9ff2dd6be1 GHActions:Windows: Enable multi-isa builds in cmake 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 4e09f903ca GS: MultiISA XXH3 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle a45f674bc1 GS: Use MultiISA ProcessorFeatures struct for SW codegen 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 75da9809e9 GS: Single build with all ISAs 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 561fb7a4be GS: Prepare for separation of multi-isa code 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle b0da6361cb GS: Mark SW renderer as multi-isa unshared 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle bc74c9064a GS: Make g_const constant initialized
We never took advantage of the ability to relocate the pointer
2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 66133b8b21 GS: GSVertexTrace Multi-ISA Support 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle b69c270c31 GS: GSLocalMemory Multi-ISA support 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle d56e6427a9 GS: Add MultiISA files 2022-12-03 00:52:10 -06:00
TellowKrinkleandTellowKrinkle 0692a9ff51 Core: Use GCC-style defines for sse detection
Much nicer for adding extensions afterwards
2022-12-03 00:52:10 -06:00
Connor McLaughlinandrefractionpcsx2 4bf6b1df5e ImGuiOverlays: Add frame time graph 2022-12-03 04:07:31 +00:00
Connor McLaughlinandrefractionpcsx2 bb7ab5690c GSRunner: Fix imgui breaking if skip dupe frames is on 2022-12-03 04:07:31 +00:00
TellowKrinkleandlightningterror c12422b2cd MTGS: Fix spinning when out of space with MTVU off 2022-12-03 02:44:25 +01:00
TellowKrinkleandlightningterror be6598e224 Threading: DarwinSemaphore.cpp things no longer need to be cancellation points 2022-12-03 02:44:25 +01:00
TellowKrinkleandlightningterror faf750a544 GS: Use semaphores with a fast userspace path 2022-12-03 02:44:25 +01:00
refractionpcsx2 ab7105ffa0 GameDB: Add fixes for Busin 0: Wizardry Alternative games. Fixes titles. 2022-12-02 20:02:13 +00:00
lightningterror e4da6829d3 InputRecording: Fix Wunused-private-field warning. 2022-12-02 20:23:25 +01:00
MrlinkwiiandGitHub 1c1d494913 GameDB: fix naming of Castlevania LoI games (#7516) 2022-12-01 23:54:41 +00:00
TheLastRarandrefractionpcsx2 a22b34ed25 DEV9: Use native APIs to check for holes 2022-12-01 21:40:31 +00:00
TheLastRarandrefractionpcsx2 31c045fdb5 DEV9: Allow sparse writing to HDD file 2022-12-01 21:40:31 +00:00
TheLastRarandrefractionpcsx2 887a1685dd DEV9: Create Sparse files 2022-12-01 21:40:31 +00:00
TellowKrinkleandtellowkrinkle ec887d5aaf GS:MTL: Clear a few warnings 2022-11-30 18:21:49 -06:00
TellowKrinkleandtellowkrinkle 08f503748e GS:MTL: Use presentDrawable on Ventura and during vsync 2022-11-30 18:21:49 -06:00
TellowKrinkleandtellowkrinkle 656f0f7b16 GS:MTL: Fix spin timer initialization 2022-11-30 18:21:49 -06:00
JordanTheToasterandrefractionpcsx2 410378dccd Qt: Tiny UI changes
Just some minor UI changes.
2022-11-29 23:50:18 +00:00
refractionpcsx2 ff22a32a61 CDVD: Escape descriptor read on iso read failure 2022-11-29 20:45:42 +00:00
lightningterror 5cdf0552ac labeler: Remove buildbot.xml 2022-11-29 12:20:01 +01:00
lightningterror d4cd8442c4 build: Remove buildbot.xml
Was used compiling and distributing builds via Orphis buildbot, no longer needed as we host the builds on our website.
Was also used for mscompile.
2022-11-29 12:20:01 +01:00
lightningterror b0430af217 build: Remove mscompile.cmd
Outdated, allowed to compile pcsx2 through command prompt.
2022-11-29 12:20:01 +01:00
refractionpcsx2 a6c22731ba GameDB: Add EE clamping for Shinobido - Way of the Ninja 2022-11-29 10:53:51 +00:00
lightningterrorandrefractionpcsx2 61b562fcaa codacy: Exclude md files. 2022-11-29 09:46:18 +00:00
lightningterror 3d551e384a workflows: Remove external shaders directory from appimage. 2022-11-29 09:46:31 +01:00
lightningterror 4cf9b7adac shaders: Remove external shaders. 2022-11-29 09:46:31 +01:00
lightningterror f76559b791 GS: Remove external shader support. 2022-11-29 09:46:31 +01:00
lightningterror ea6d276a46 config: Remove external shader support. 2022-11-29 09:46:31 +01:00
lightningterror a323145344 gui-wx: Remove external shader support. 2022-11-29 09:46:31 +01:00
lightningterror 26aa7ef09f MemoryCardFile: Fix Wunused-result warnings. 2022-11-29 01:55:22 +01:00
lightningterror 4a5f9df7bf Sio: Fix Wunused-variable warning. 2022-11-29 01:55:22 +01:00
PCSX2 Botandlightningterror f2a9c8558b PAD: Update to latest controller database. 2022-11-28 18:22:54 +01:00
Tyler Wildingandrefractionpcsx2 07c3b6ad04 input-rec: remove input recording code from wx-related source 2022-11-28 14:25:11 +00:00
JordanTheToasterandrefractionpcsx2 8cbdd61f98 GameDB: Fixes for HP OFTF and MLB 2K5
FIxes freezing and stuttering in MLB 2K5 and ghosting and vertical lines in HP OFTF.
2022-11-28 13:57:34 +00:00
lightningterror 276b1b5539 iR3000A: Fix variable is assigned a value that is never used warning.
Codacy.
2022-11-28 01:33:01 +01:00
lightningterror fbc4a5cac2 PAD: Fix variable is assigned a value that is never used warnings.
Codacy.
2022-11-28 01:33:01 +01:00
lightningterror 8b01fb0bcf USB: Fix variable is assigned a value that is never used warnings.
Codacy.
2022-11-28 01:33:01 +01:00
lightningterror f565014203 GS-sw: Fix Winconsistent-missing-override warning. 2022-11-28 01:33:01 +01:00
Tyler Wildingandrefractionpcsx2 3a048dafab gui/qt: allow the opened recording to be closed 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 7383bc3f44 input-rec: remove integration from SIO/Counters, fix imgui updating 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 96d9eadb4b gui/wx: disable input recording on the wxWidgets side 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 199db12565 input-rec: integrate with new SIO code 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 f66ea63b7e input-rec: ensure wx code is frozen for PadData files 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 bed53be218 input-rec: fix captialization of IRFile function names 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 af1e41681c input-rec: move IRFileHeader & IRSavestate privately into the IRFile class
+ Add getters for the header char array variables. No longer allow direct access to header content outside of the class.
2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 7987430825 input-rec: Always show current GSFrame on any savestate load or reset
Knowing the frame count after either can be very useful, so that should be displayed regardless of the blank screen.
2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 592395d15c input-rec: Set frame count to zero on "reset" 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 5cd243f2c1 input-rec: disable the "Reset" option when a recording uses a savestate 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 f699807cae input-rec: updates to bulk read implementation
+ Handles edge cases where the file is too small
+ Minor performance optimizations around reserving vector memory space
+ Simpler file seeking
2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 31b7ec7308 input-rec: recording viewer touchup 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 5ea882dae3 input-rec: remove excessive returns in ControllerInterrupt 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 1628237ba7 input-rec: replace u64s with u32
+ Converts g_inputRecordingFile's total frame count to unsigned long to match.
2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 b86241695d input-rec: remove private InputRecordingFile::open()
The code that gets ran by each branch differs enough that just moving them into openNew() & openExisting() is more beneficial. Removes the unnecessary runtime boolean check.
2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 7bab2d197e input-rec: touch up InputRecordingFile.h/.cpp 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 6288f945cd input-rec: refactor PadData button state control 2022-11-27 20:02:29 +00:00
sonicfindandrefractionpcsx2 1356171af5 input-rec : additional m_/s_ variable tags and constexpr placements 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 409c285f36 input-rec: refresh imgui overlay when recording mode changes while paused 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 844ff5bb04 input-rec: fix running input recording functions from UI thread 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 6ae9e7edb5 input-rec: facilitate changing controls immediately for certain edge-cases 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 a38fbb157d input-rec: necessary renaming on the wx side 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 b4db00b979 input-rec: display recording related information with imgui 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 142a1a392f input-rec: wire up changes to the rest of the project 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 c98b90a4e2 input-rec: cleanup irrelevant input recording controls 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 c5298cf12d input-rec: refactor main input recording class 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 9e30fa81de input-rec: refactor and cleanup the file and logging classes 2022-11-27 20:02:29 +00:00
Tyler Wildingandrefractionpcsx2 8f5458f3ae input-rec: Add very basic file viewer to assist with debugging 2022-11-27 20:02:29 +00:00
refractionpcsx2 0a8f5e97e4 GS-HW: Update validity when resizing a texture during the draw. 2022-11-27 19:15:59 +00:00
refractionpcsx2 92bec955a8 GS-SW: Revert software clamp changes from large TH/TW PR.
This change didn't need to be done as the th and tw are sized based on the actual sizes anyway, if these are wrong, the software renderer can crash when trying to draw out of bounds, so this needs to stay as it is.
2022-11-27 08:47:46 +00:00
Connor McLaughlinandrefractionpcsx2 89c0d95a94 Common: Slim down RedtapeWindows and correct case 2022-11-27 03:45:54 +00:00
xantaresandrefractionpcsx2 2c88cd7ac0 CMake: Lowercase Winmm for case-sensitive fs
Fix build on mingw from linux
2022-11-26 19:05:58 +00:00
xantaresandrefractionpcsx2 0440079a24 FileSystem: Use _stat64 routines 2022-11-26 19:05:49 +00:00
xantaresandrefractionpcsx2 5fbf21c1bd RedtapeWindows: Lowercase includes for linux fs 2022-11-26 19:03:15 +00:00
refractionpcsx2 e4cc0e04e8 GS-DX11: Fix D3D11_BOX parameters (missing "front") 2022-11-26 18:24:12 +00:00
refractionpcsx2 01179c69ec CDVD: Correct DMA timing if sectors are buffered. 2022-11-26 18:03:05 +00:00
Connor McLaughlinandrefractionpcsx2 038e22e5db MTGS: Make PresentCurrentFrame() callable from CPU thread
GS thread can use GSPresentCurrentFrame().
2022-11-26 16:32:39 +00:00
Connor McLaughlinandrefractionpcsx2 ebeba2ba17 GS/Vulkan: Enable samplerAnisotropy before using 2022-11-26 16:17:20 +00:00
Connor McLaughlinandrefractionpcsx2 daebb5753a GS/HW: Fix various issues with texture replacements
- Replacement textures now show in HC usage to give a clearer picture
   of VRAM usage.
 - Fixed crashes when loading compressed and mipmapped DDS textures.
 - Fixed compressed mipmapped textures in Direct3D 12.
 - Fixed GPU crashes in D3D11/D3D12/Vulkan when compressed textures went
   down the last 1x1 mipmap level.
2022-11-26 16:17:20 +00:00
TellowKrinkleandtellowkrinkle bb2016889a 3rdparty: Update SDL to 2.26.0 2022-11-25 23:47:32 -06:00
EdnessPandGitHub 470bbc9899 Patches: Add extended PS2rd support; used by OPL (#7381) 2022-11-26 05:07:36 +00:00
refractionpcsx2 527fa587ce CDVD: Don't account for rotation if sectors are buffered 2022-11-26 05:04:49 +00:00
refractionpcsx2 8a22e44f3b GS-TC: Make sure if we have an old frame check bounds of other frame 2022-11-26 05:04:38 +00:00
RedDevilusandrefractionpcsx2 ad7736f90d GameDB: Remove blit from PAL being dumb
The gamefix works well for NTSC, but I had added blit to every version of resident evil doing wrong fixes which were meant for Silent Hill 4 and forget this part where it only gives 10 FPS instead of more.
2022-11-26 03:59:00 +00:00
AKuHAKandrefractionpcsx2 2ab27ef42a formatter: apply editorconig into various files 2022-11-25 22:41:00 +00:00
TellowKrinkleandrefractionpcsx2 314c840293 VIF: Reduce alignment of empty hash buckets
They'll never be in hot codepaths (since they're empty) and memalign with 64-byte alignment is noticeably slower than 16-byte alignment
2022-11-25 20:20:24 +00:00
TellowKrinkleandrefractionpcsx2 ee451fe345 Common: Fix slow emulator startup on M1s 2022-11-25 20:20:24 +00:00
JordanTheToasterandrefractionpcsx2 50f90aee79 GameDB: Fix incorrect name of SLPM-65140
Fixes an incorrect game name.
2022-11-25 19:51:10 +00:00
Connor McLaughlinandrefractionpcsx2 31c02e5915 FullscreenUI: Don't show game fixes unless advanced is enabled 2022-11-25 16:46:26 +00:00
Connor McLaughlinandrefractionpcsx2 d08f4df146 ImGuiFullscreen: Fix navigating to root on Linux 2022-11-25 16:46:26 +00:00
JordanTheToasterandrefractionpcsx2 e17f592602 GameDB: Set texture preloading to Partial for Espagaluda
Setts texture preloading to partial to almost double the speed of the game because it's stupid and seems to absolutely destroy the HC.
2022-11-25 15:27:46 +00:00
lightningterror 50bb362dc9 GS-hw: Further optimize blending equations.
Allow to run free sw blend with no texture barriers, more speed for all renderers.

CLAMP 1, negative result will be clamped to 0.
Condition 1:
(0  - Cs)*Alpha +  0, (0  - Cd)*Alpha +  0
Condition 2:
Alpha is either As or F higher than 1.0f
(0  - Cd)*Alpha  + Cd, (0  - Cs)*F  + Cs
2022-11-25 15:04:04 +01:00
Mrlinkwiiandrefractionpcsx2 1d1ee314ca GameDB:Fixing some minor typos 2022-11-25 10:31:31 +00:00
Connor McLaughlinandrefractionpcsx2 db8fb7f5a3 AppImage: Don't change current working directory 2022-11-25 10:25:28 +00:00
refractionpcsx2 498fe48255 GS: Combine dirty rects when having matching edges 2022-11-24 11:43:16 +00:00
Connor McLaughlinandrefractionpcsx2 2b75f9638d GS/DX12/Vulkan: Handle out-of-VRAM better
Instead of immediately failing the allocation, flush the texture pool,
and execute/wait for the command buffer. This will clear out any
textures which have already been freed, and the storage can be reused
for.
2022-11-24 10:38:53 +00:00
Connor McLaughlinandrefractionpcsx2 f159d1de55 GS/TextureCache: Better handle batched tiny moves
e.g. Dark Cloud's menu.

Also prevents an out-of-VRAM situation from crashing.
2022-11-24 10:38:53 +00:00
Connor McLaughlinandrefractionpcsx2 eb67c87e20 FullscreenUI: Match settings grouping with Qt 2022-11-24 09:46:49 +00:00
Connor McLaughlinandrefractionpcsx2 95953c86ae VMManager: Write unsafe settings to emulog 2022-11-24 09:46:49 +00:00
Connor McLaughlinandrefractionpcsx2 f8bd4d7155 Qt: Shuffle some settings around/hide advanced by default 2022-11-24 09:46:49 +00:00
RedDevilusandrefractionpcsx2 4d73147121 GameDB: Fixes to multiple games yet again
- Thrillville + Thrillville Off The Rails: Mad TFF / deinterlace 8 to stop shaking the whole game
- Forgotten Realm Demon Stone: Get rid of more blur
- ATV Offroad Fury 3: MTVU disabled which was an odd find to improve FPS
- Crimson Tears: Wild arms + Full Sprite for reducing bloom misalignment + note that Blending TFF might be better especialy when you use Software.
- Final Fantasy X: Texture in Rt for fixing endgame summons like Anima and The Magus Sisters
- No One Lives Forever: Mipmap full + trilinear + full blending needed to fix lighting
2022-11-23 22:02:06 +00:00
lightningterror 0466114f67 gui-wx: Add FidelityFX CAS support.
Add FidelityFX CAS support to wxwidgets.
Rename Texture Filtering of Display to Bilinear filtering.
Remove Debug box.
Misc cleanup.
2022-11-23 22:52:10 +01:00
lightningterror 0a585e00e5 gui-wx: Add default configs for CAS filtering. 2022-11-23 22:52:10 +01:00
JordanTheToasterandrefractionpcsx2 5048f1c21b GameDB: Remove Round Sprite from POPSOT
Removes round sprite from prince of persia sands of time as it causes lines to appear in post processing.
2022-11-23 21:27:31 +00:00
icup321andGitHub 486c823111 GameDB: Fixes for Finding Nemo, Haven: Call of the King, Kinetica
#7396
2022-11-23 19:44:17 +00:00
refractionpcsx2 7e66eb856c GS: Add sharp bilinear post filter
Remove internal screenshot setting, all screenshots are internal (and it wasn't hooked up)
2022-11-23 17:28:54 +00:00
Connor McLaughlinandrefractionpcsx2 edb9a5ba3c Qt: Add -testconfig option 2022-11-23 15:55:39 +00:00
Connor McLaughlinandrefractionpcsx2 6f354c6c02 Qt: Move post-processing options into its own tab 2022-11-23 11:45:37 +00:00
TellowKrinkleandrefractionpcsx2 2fb8ecbf02 GS:MTL: CAS support 2022-11-23 11:45:37 +00:00
Connor McLaughlinandrefractionpcsx2 f7c79fe3cc GS: Implement FidelityFX CAS 2022-11-23 11:45:37 +00:00
Connor McLaughlinandrefractionpcsx2 5363a90c6b D3D12: Add compute shader support 2022-11-23 11:45:37 +00:00
Connor McLaughlinandrefractionpcsx2 d132ddefef GL: Add support for compute shaders 2022-11-23 11:45:37 +00:00
TellowKrinkleandrefractionpcsx2 46db4077b8 Common:Vulkan: Add storage descriptors to pool
Needed for CAS
2022-11-23 11:45:37 +00:00
Connor McLaughlinandrefractionpcsx2 344d27ea5a Vulkan: Add ComputeShaderPipelineBuilder 2022-11-23 11:45:37 +00:00
TellowKrinkleandrefractionpcsx2 2dfb819d35 Resources: ffx_cas.h Metal support 2022-11-23 11:45:37 +00:00
TellowKrinkleandrefractionpcsx2 cef8d03d49 Resources: ffx_a MSL support 2022-11-23 11:45:37 +00:00
Connor McLaughlinandrefractionpcsx2 4177b090b2 Resources: Add GPUOpen's FidelityFX CAS headers 2022-11-23 11:45:37 +00:00
refractionpcsx2 26075a9520 GS-HW: Remove mistake from old frame PR 2022-11-23 10:27:03 +00:00
JordanTheToasterandrefractionpcsx2 76b88ebdbf GameDB: Add fixes for Demon Chaos
Adds auto flush and half pixel offset special texture to fix missing bloom and misaligned bloom and lighting.
2022-11-23 09:24:57 +00:00
TellowKrinkleandtellowkrinkle bae4a2df7e GS:MTL: Fix mad shader on M1 2022-11-23 00:57:03 -06:00
refractionpcsx2 e8ce1e3445 GS-TC: Only reset age when it's definitely an EE write 2022-11-22 20:00:31 +00:00
AKuHAKandrefractionpcsx2 90a4025bcc BiosTools: improve region codes
Region code numbering now matches regions inside CDVD_internal.h
Added region assignment for non-standard romver
Renamed HK region to Asia as 'H' covers not only Hong Kong, but also Korea and Taiwan
2022-11-22 17:19:01 +00:00
Connor McLaughlinandrefractionpcsx2 f66797c5cf Qt: Add option to reset play time for games 2022-11-22 17:14:56 +00:00
Connor McLaughlinandrefractionpcsx2 bd22d29d58 Host: Make OSD message timing consistent
It was all over the place previously.
2022-11-22 17:14:56 +00:00
Connor McLaughlinandrefractionpcsx2 5026dda9ca Qt: Fix Enable Per-Game Settings option 2022-11-22 17:14:56 +00:00
Connor McLaughlinandrefractionpcsx2 b30e93389c GS/OpenGL: Remove disable_hw_gl_draw option
I'm not sure what the point of it ever was..
2022-11-22 14:56:57 +00:00
refractionpcsx2 a2a635a141 GS: Favour newer targets unless no match found. No age update on frame. 2022-11-22 10:51:09 +00:00
refractionpcsx2 05dd0831c1 GS: Avoid large clears in HW 2022-11-22 10:51:09 +00:00
refractionpcsx2 db788452bd PAD: increase number of macros per controller from 4 to 16 2022-11-22 10:50:44 +00:00
JordanTheToasterandrefractionpcsx2 5c5fdcf14d Qt: Change dump compression to Zstandard
Until XZ stops exploding we should default to Zstandard for dump compression.
2022-11-22 10:50:28 +00:00
RedPanda4552andrefractionpcsx2 b96a252a61 Memory Card: Make access denied pop-up actually explain the problem 2022-11-22 00:08:24 +00:00
PCSX2 Botandlightningterror 793aa7fd7f PAD: Update to latest controller database. 2022-11-21 18:43:37 +01:00
Connor McLaughlinandrefractionpcsx2 d0673f9133 Sio: Fix host pointer getting serialized
[SAVEVERSION+] It wasn't saving the FIFO anyway. Sorry for the save
state bump, but it's unavoidable :(
2022-11-21 13:40:01 +00:00
lightningterror 4b4b82bd5f Readme: Mention that win 8.1 was dropped after 1.6 stable. 2022-11-20 22:28:43 +01:00
lightningterror dda0b6c296 common: Drop windows 8.1 and server 2012 r2 support.
We already require windows 10 (build 1809) with the recent recompiler changes.
2022-11-20 22:28:43 +01:00
refractionpcsx2 e212c611be GS-HW: Expand target on EE write and improve overlap check 2022-11-20 18:51:13 +00:00
refractionpcsx2 a95492f7a0 GS-TC: Only reset age on new Tex in RT targets.
Caused huge GS usage on Urban Reign due to old target.
2022-11-20 18:50:40 +00:00
refractionpcsx2 ff3c22fc2b GS: Allow negative offset on single display 2022-11-20 18:50:21 +00:00
Mrlinkwiiandrefractionpcsx2 59e8a2dfae GameDB: add fixes to 'Car Racing Challenge' 2022-11-20 18:25:41 +00:00
JordanTheToasterandrefractionpcsx2 d44e215e5e GameDB: Add Blit gamefix to Worms 4
Adds Blit gamefix to Worms 4 Mayhem to fix internal FPS detection.
2022-11-20 18:25:17 +00:00
Connor McLaughlinandrefractionpcsx2 129fddf07c Qt: Switch to 6.4.0 on Windows 2022-11-20 17:25:55 +00:00
Connor McLaughlinandrefractionpcsx2 0dd766cec8 Qt: Work around theme switching issue in 6.4.0
Starting in dark theme then switching to native/light would not restore
the standard palette.
2022-11-20 17:25:55 +00:00
Mrlinkwiiandrefractionpcsx2 f79b57d0cf Gamedb: add fixes to 'Sega Rally 2006' 2022-11-20 17:22:34 +00:00
refractionpcsx2 226b188eaf WX-UI: Fix deinterlace dropdown. 2022-11-20 16:25:32 +00:00
Connor McLaughlinandlightningterror 8f4e01e004 CI: Change Windows builders to VS2022 2022-11-20 11:35:16 +01:00
JordanTheToasterandtellowkrinkle d54dab87ef Metal: Fix usage of MAD
Fixes pink or frozen images of the last frame in games when using MAD with Metal.
2022-11-20 00:47:01 -06:00
Connor McLaughlinandrefractionpcsx2 ef8e35032e x86/iR5900: Don't swap loadstore delay slots for BC0/BC2 conditions
Swapping the loadstore could affect the condition of the instruction,
leading to incorrect code execution.

Fixes lock up in Oni after intro FMVs.
2022-11-20 04:47:08 +00:00
Connor McLaughlinandrefractionpcsx2 599e291824 R5900: Fix disassembling of BC0 instructions 2022-11-20 04:47:08 +00:00
TellowKrinkleandrefractionpcsx2 3d8fe01bc6 Input:DInput: Fix build after adding FullAxis support for SDL 2022-11-20 02:40:07 +00:00
TellowKrinkleandtellowkrinkle a72cecd235 Input: Add FullAxis modifier 2022-11-19 19:16:52 -06:00
TellowKrinkleandtellowkrinkle 02a2e8a7f1 Input:SDL: Support Joystick axes that aren't used in GameController mappings 2022-11-19 19:16:52 -06:00
TellowKrinkleandtellowkrinkle 38c1b031c2 Input:SDL: Allow use of axes and buttons outside the normal range 2022-11-19 19:16:52 -06:00
lightningterror 3ba72e8728 MemoryCardFolder: Fix Wsign-compare warning. 2022-11-19 19:28:52 +01:00
lightningterror 5286b19af5 MultitapProtocol: Fix Wtype-limits warning. 2022-11-19 19:28:52 +01:00
lightningterror 5c104f8e1d common linux: Fix Wunused-variable warning. 2022-11-19 19:28:52 +01:00
lightningterror 0988b08f7a GS interlace: Fix Wreturn-type, Wunused-variable, Wsometimes-uninitialized warnings. 2022-11-19 19:28:52 +01:00
lightningterror bfcd5c84ca IopHwRead: Fix Wmaybe-uninitialized warning. 2022-11-19 19:28:52 +01:00
lightningterror 93b24f98a6 microVU_Macro: Fix Wunused-variable warning. 2022-11-19 19:28:52 +01:00
lightningterror 32d52cb0dd recVTLB: Fix Wsign-compare warnings. 2022-11-19 19:28:52 +01:00
lightningterror 552d5d8928 iR5900Templates: Fix Wunused-variable warnings. 2022-11-19 19:28:52 +01:00
lightningterror 5b583fefbc MemoryCardProtocol: Fix Wimplicit-fallthrough warnings. 2022-11-19 19:28:52 +01:00
lightningterror 3c4d48f45d SIO: Fix Wunused-variable warning. 2022-11-19 19:28:52 +01:00
lightningterror f6b8b6cb9b gui-wx: Fix Deinterlace option. 2022-11-19 18:20:28 +01:00
Mrlinkwiiandrefractionpcsx2 78cf98dcb7 Build.sh : remove refernces to coverity 2022-11-19 16:55:34 +00:00
Mrlinkwiiandrefractionpcsx2 13e95ad5cb Readme: update Minimum and Recommended specs 2022-11-19 16:55:34 +00:00
Connor McLaughlinandrefractionpcsx2 5ab4263c0a MemoryCardFolder: Add missing bounds check to Read() 2022-11-19 16:55:16 +00:00
refractionpcsx2 77ea599e36 GameDB: Add Mipmap Full + Trilinear for Shadow of the Colossus 2022-11-19 07:07:21 +00:00
Connor McLaughlinandrefractionpcsx2 6793a84f9b x86/iR5900: Fix compiling with DUMP_BLOCKS 2022-11-19 06:16:44 +00:00
Connor McLaughlinandrefractionpcsx2 9ab449dcf3 3rdparty/zydis: Silence static define warning 2022-11-19 06:16:44 +00:00
Connor McLaughlinandrefractionpcsx2 c883e9d792 Sio: Only eject memory cards when loading state if changed
[SAVEVERSION+] Regression from #6741.
2022-11-19 06:01:09 +00:00
Connor McLaughlinandrefractionpcsx2 0e73bf1e6d SaveState: Only remap changed TLB slots on load 2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 1ccddb92d4 EE Rec/IOP Rec: Rewrite large portions
- Add fastmem
 - Add delay slot swapping
 - Add COP2 sync elision
 - Add block analysis and use analysis
 - Add GPR register caching and renaming
2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 56501e0811 x86emitter: Fix up emitting of xmm -> ptr64 operands 2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 3d6a550f23 x86Emitter: Add 8-bit variants for spl..r15b
Also fixes PINSR/PEXTR.
2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 8de4e190dc EERec: Disable large block splitting 2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 d17ceec14b EERec: Add block dumping 2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 741ddaf384 3rdparty: Add zydis 2022-11-19 04:59:10 +00:00
Connor McLaughlinandrefractionpcsx2 76b03a8a88 VSProps: Use MultiToolTask mode
Much better parallelism, due to our source files being spread out across
multiple folders.

pcsx2core build time on a Ryzen 3900X with 12C/24T:

Before: Time Elapsed 00:00:26.74
After: Time Elapsed 00:01:03.21
2022-11-19 04:58:23 +00:00
Connor McLaughlinandrefractionpcsx2 fd194124a9 x86: Move cycle/writeback fields to CPU structs
[SAVEVERSION+] Potentially better locality, keeps everything we're
accessing from the rec together.
2022-11-19 03:54:02 +00:00
RedDevilusandrefractionpcsx2 ff7053c566 GameDB: Fixes multiple games for Xth time and more
Bakugan: Deinterlace adaptive tff due to the game attempting to deinterlace FMVs but PCSX2 going nuts
Driv3r: Fixes janky coloured cars with cpuCLUT
Megaman X8: Deinterlace blending tff due to either looking like missing half the text or flicker as how the game handles empty and subtitles
Tales of Destiny 1: Texture preload partial for better performance in certain areas
2022-11-19 03:00:17 +00:00
refractionpcsx2 be438587c7 mVU: Clean up range function and improve merging. Slim down cmpProg. 2022-11-19 02:35:25 +00:00
RedPanda4552andrefractionpcsx2 1146175648 SIO: Separate SIO2 from SIO0, reimplement memcard protocol
[SAVEVERSION+] Fixes memcard issues in MGS3, Shining Force EXA, and others which do 4 sector reads
2022-11-19 02:08:13 +00:00
lightningterror 3f99d1d3cc GameDB: Change mipmap to full and add trilinear ps2 for Die Hard - Vendetta.
Further improves ground rendering.
Improves #5127
2022-11-19 01:45:08 +01:00
lightningterror af58273c4c GameDB: Add basic mipmap to Winning Post 4 Maximum 2001 and Winning Post 5 Maximum 2002.
Improves ground textures rendering.
Close #4923
2022-11-19 01:28:57 +01:00
sideprojectslabandrefractionpcsx2 93abf66240 GameDB: forced Alpine Racer 3 deinterlacing to Adaptive BFF when Auto 2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 6924249bcf GS: Reverted field order in MAD shader updated weave shader to same field order as MAD and merged two Weave shaders into one
GS: corrected refactoring errors in interlace shaders
2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 21fa2ee87b GS: Improved MAD compatibility with other graphics settings 2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 50861dc5c1 UI/GameDB: fixed issues with MAD integration in UI and GameDB
GameDB: fixed compile error
2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 64f6bf52b0 GS: Cleaned up and commented Motiond Adaptive Deinterlacing shader code
GS: fixed compile error in Metal interlace shader
GS fixed more compile errors in Metal interlace shader
GS: Adjusted code indentation in interlace shader for all renderers
2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 e9d256aa74 INI: created new deinterlace_mode config setting to force new default to Automatic 2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 79b5f2154f GS: added Motion Adaptive Deinterlacing support for Metal renderer 2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 0f42eab7a4 UI: Integrated Motion Adaptive Deinterlacing with UI
[SETTINGSVERSION+]
Added entries in the drop-down menu for Adaptive Deinterlacing
Re-arranged deinterlacing mode order in the drop-down menu.
"Auto" mode defaults to MAD.
Adjusted GameDB entries to be compatible with the new order of entries.
Improved Bob description for WX
2022-11-18 21:29:37 +00:00
sideprojectslabandrefractionpcsx2 f10e7f4ab7 GS: Implemented Motion Adaptive Deinterlacing for all renderers
implemented FastMAD motion-adaptive deinterlacing for OpenGL renderer, other renderers will crash. FastMAD is replacing blend (either mode) so select blend to activate MAD under the hood

fixed an assert and assessed that one MUST select mode Blend bottom field first to enable MAD

removed forced mode 2, added separate motion thresholds for current field and alternate field motion and optimized MAD for Top-FIeld-First mode

committing kind-of broken status for review

the algorithm works well on most games, but somehow Kingdom Hearts works at half resolution

completely fixed weird artifacts on MAD, I only need to fix a 1-line offset that is causing the top of the screen to flicker

fixed flicker on first line, I still need to fine-tune some coefficients

solved all nastiness by realizing that MAD MUST work on an even resolution, so odd resolutions are rounded up. Now all games I tried look great

made MAD sensitivity adjustable inside GDDevice.h and passed to shaders as a parameters. For this purpose ZrH is now a vec4 to hold more parameters conveniently

ported MAD to DX11 and DX12

removed rounding of texture size to closest multiple of 2 and fized odd number of lines inside the shaders by also passing the vertical resolution as a parameter

improved compatibility of upper buffer offset adjustment for odd resolutions

added Vulkan support
2022-11-18 21:29:37 +00:00
Ty Lamontagneandrefractionpcsx2 e1f7fe5700 GIF: Fix MFIFO DMAStalls. Fix InstantDMA with PSE bit set 2022-11-18 01:55:43 +00:00
JordanTheToasterandrefractionpcsx2 ebfd656c54 GameDB: Add fixes for Shadow Hearts Covenant
Adds Round Sprite Full and Auto Flush to Shadow Hearts Covenant to make the shadow monsters appear and fix garbage in the UI.
2022-11-18 01:55:31 +00:00
refractionpcsx2 630ebb0583 GS: Expand "progressive" analogue games to full height, in case they lie 2022-11-18 01:32:09 +00:00
JordanTheToasterandrefractionpcsx2 748dcbd989 ImGuiOverlays: Add missing fixes
Adds the last of the fixes to the overlay
2022-11-18 00:38:14 +00:00
Mrlinkwiiandrefractionpcsx2 c0b4ceef0b GameDB: add InstantDMAHack to King of Colosseum - Red/Green 2022-11-17 22:20:03 +00:00
refractionpcsx2 8ba768ecec GIF: Fix reset functionality to properly abort the current packet 2022-11-17 11:18:48 +00:00
refractionpcsx2 cfb5e203b3 GS-HW: Increase channel shuffle sizes to resolution or higher.
GS-TC: Fix small bug which could end up with an invalidation being skipped.
2022-11-17 11:18:24 +00:00
lightningterror 433e42e3e4 GameDB: Fix bad formatting failing ci. 2022-11-17 02:34:05 +01:00
lightningterror 1519a6b1da GameDB: Add full mipmap + trilinear ps2 to Virtua Tennis 2.
Game requires full mipmap + trilinear ps2 to match ground to sw renderers.
Close #5961
2022-11-17 02:13:34 +01:00
RedDevilusandrefractionpcsx2 87abacc632 GameDB: Fix multiple games + maintenance
- Area 51: Half Pixel Normal vertex for lighting and other places
- Shrek 2: Basic mipmapping which kinda half fixes the sun missing
- Galaxy Angel II: Normal vertex which reduces misalignment
- Forgotten Realms - Demon Stone: Clamping Mode extra + preserve which will solve the occasional SPS + missing demo entry.
- Spyro Dawn of dragon: SW clut + sprite which doesn't make you vomit from the overbloomification and looks similar to the software renderer
- Castlevania Curse of darkness half sprite which will enlarge the font similar to software renderer + some missing fixes that were available on the Europe and America versions but not Japanese.
- Drakengard 1 + 2 (Also know as Drag-on Dragoon) : Partial (no hashcache) to avoid slow transitions and other areas. Adds missing Japanese Drakengard 1
- Urban reign: Partial texture preloading to fix performance issues in the gameplay
- Onimusha Warlord: Partial preloading to fix performance issues
- Sniper Elite: Fix sky lighting
- Maintenance that add spaces in the titles for Disc1of1 to Disc 1 of 1 and more...
2022-11-16 20:35:37 +00:00
RedDevilusandlightningterror e5bc1defa2 Documentation: VSCode integration addendum + y2022
- GameIndex.md updated with the year 2022.
- GameIndex.pdf updated with VSCode integration for yaml.
2022-11-15 18:12:49 +01:00
lightningterror c975a78ed7 GameDB: Add autoflush to Jak X combat racing and add comments to the fixes. 2022-11-15 17:39:56 +01:00
lightningterror 4537342ec2 FullscreenUI: Fix Wunused-variable warnings. 2022-11-15 16:47:51 +01:00
lightningterror ee80bca994 GS: Fix Wunused-variable warnings. 2022-11-15 13:03:51 +01:00
lightningterror 55c1012d1c GS: Fix Wsign-compare warnings. 2022-11-15 13:03:51 +01:00
Tyler Wildingandlightningterror df5a7d4fb1 ci/lint: add InstantDMAHack to valid list of game fixes 2022-11-15 12:15:42 +01:00
Tyler Wildingandlightningterror fba0e5932f ci: use the json schema to validate the GameDB 2022-11-15 12:15:42 +01:00
Tyler Wildingandlightningterror 28c2c8d179 docs: update relevant documentation 2022-11-15 12:15:42 +01:00
Tyler Wildingandlightningterror d1459650e1 ci/lint: remove GameDB python lint script, replace with json-schema 2022-11-15 12:15:42 +01:00
Ty Lamontagneandrefractionpcsx2 6138ac009f Core: Sign extend the interpreter impl of MFC0 2022-11-15 08:50:00 +00:00
PCSX2 Botandlightningterror aa4a9cdad7 PAD: Update to latest controller database. 2022-11-14 17:06:34 +01:00
Connor McLaughlinandrefractionpcsx2 a7af3cd483 x86/microVU: Write VIs from CTC2 as 16 bits
The micro recompilers only write as 16 bit, so in case the value in the
register was greater than 0xFFFF, we don't want to store higher bits
that get stuck.
2022-11-13 16:15:36 +00:00
Connor McLaughlinandrefractionpcsx2 a12accf3fa x86/iR5900: Align LQC2/SQC2 to 16 bytes
LQ/SQ were already 16 byte aligned.
2022-11-13 16:15:36 +00:00
David Scholbergandrefractionpcsx2 ffe669137b Qt: fix inhibit screensaver on Linux (X11)
This change fixes https://github.com/PCSX2/pcsx2/issues/7367.
xdg-screensaver expects the given window ID to be that of the top level
window.
2022-11-13 09:29:41 +00:00
refractionpcsx2 a874c5455d GS-TC: Reset age on Host->Local dirty textures 2022-11-12 21:47:36 +00:00
refractionpcsx2 d70b7e5bc7 GS-TC: Don't shufflemove data which isn't in the texture.
Allowing this could expand the texture to just be black, causing bad copies.
2022-11-12 21:46:44 +00:00
refractionpcsx2 8e80662bb0 GS-TC: Invalidate videomem still if surface becomes invalid 2022-11-12 21:46:34 +00:00
refractionpcsx2 dbd7d2e290 GS: Correct the height on reversed local->local transfers
Also avoid messing around in reverse if possible
2022-11-12 21:46:13 +00:00
Silentandrefractionpcsx2 93d948ac57 GameDB: Added HPO Special to The Getaway and The Getaway: Black Monday 2022-11-10 10:30:10 +00:00
Silentandrefractionpcsx2 c69c7ce59c GS/TextureCache: Add a CRC hack in InvalidateVideoMemType for Getaway games 2022-11-10 10:30:10 +00:00
refractionpcsx2 79c79b06ca GS: Don't add overscan to offsets when looking up output texture.
This can cause mis-detection when Show Overscan is enabled, making it miss the target.
2022-11-10 09:28:45 +00:00
RedDevilusandrefractionpcsx2 b922667fbd GameDB: Multiple fixes for games
V-Rally: Fixes fog and lights on car
Okami: Adds missing Korean entry + Full Round for misaligment
Colosseum: Road to Freedom (Or Gladiator in Japan): Fixes the sunlight in the window in the selection screen
Chronicles of Narnia, Prince Caspian (2nd game in series): Fixes broken upscaling in different areas such as screen and new game
Gakuen Alice: Reduces vertical line issue in textbox
Monster Lab: Fix slow speed due to high hash cache usage
Naruto Shippuden - Ultimate Ninja 4
Dragon Ball Z Tenkaichi 1 + 3: SW clut instead of CRC hack
Deletes double punctation in a comment and changed 3d to 3D. Rename all Dragon Ball games correctly with spaces and uppercases. Fix apostrophes on game serial.
2022-11-10 09:28:14 +00:00
refractionpcsx2 9bfe89f115 CDVD: Adjust rotational delay after seek behaviour 2022-11-09 22:49:10 +00:00
Ty Lamontagneandrefractionpcsx2 4975f7f098 Profiling: Fix QT builds where USE_VTUNE is true 2022-11-09 19:00:11 +00:00
JordanTheToasterandrefractionpcsx2 4db49038c8 GameDB: Add VU Clamp Extra+Sign to Lego Starwars
Adds VU Clamp Extra+Sign to Lego Starwars to fix bad coordinate spam.
2022-11-09 18:45:19 +00:00
JordanTheToasterandrefractionpcsx2 4cc7ec5a02 GameDB: Add CPU CLUT to Bionicle Heroes
Adds CPU CLUT Normal to Bionicle Heroes to fix ghosting.
2022-11-09 18:03:02 +00:00
JordanTheToasterandrefractionpcsx2 930de813f7 GameDB: Add CPU CLUT to Lego Starwars 2
Adds CPU CLUT normal to Lego Starwars 2 to fix ghosting.
2022-11-09 12:33:32 +00:00
refractionpcsx2 e9ec9e79ac GS-HW: Assume points of right size are paletted, regardless of Z writes.
Adds Clannad CLUT setting in the gamedb.
2022-11-09 10:24:47 +00:00
Tyler Wildingandrefractionpcsx2 212b2aea16 releases: allow publishing discord announcements to multiple webhooks 2022-11-08 17:44:00 +00:00
JordanTheToasterandrefractionpcsx2 06a0dc374f GameDB: Set texture preloading to Partial for Keihin Keikyu Train Simulator
Set texture preloading to Partial for Keihin Keikyu Train Simulator
2022-11-08 12:12:38 +00:00
Mrlinkwiiandrefractionpcsx2 1cc63412ec GameDB : add upscaling fixes to 'Headhunter - Redemption'
GameDB : add upscaling fixes to 'Headhunter - Redemption'
2022-11-08 11:05:33 +00:00
refractionpcsx2 39c35d4430 Updater: Check for [SAVEVERSION+] etc before clearing out most of the message. 2022-11-07 21:34:02 +00:00
PCSX2 Botandlightningterror 10699b7c09 PAD: Update to latest controller database. 2022-11-07 21:24:06 +01:00
Risaeandrefractionpcsx2 25c807965c GameDB: Disable gsHWFixes for Growlanser 5 & 6 2022-11-07 19:11:07 +00:00
refractionpcsx2 5321ca913e EE: Implement Instant DMA hack for some cache problematic games
Bump savestate version for new dma stall flag

[SAVEVERSION+]
2022-11-07 18:56:04 +00:00
refractionpcsx2 b8c7ac4529 GS: On Local->Local transfer wrap around 2048 2022-11-07 09:46:27 +00:00
MomosuWarosuandrefractionpcsx2 5b98c0b7ff GameDB: Add Wild Arms Hack to Kaido Battle games, and RBC1GP. 2022-11-07 09:46:11 +00:00
refractionpcsx2 7ed4e3ae35 GS-HW: Further restrict CLUT heuristics.
Reduces readbacks in Burnout by like 75%
2022-11-06 17:02:59 +00:00
refractionpcsx2 250b266321 GS: Pass original height for feedback lookup. 2022-11-05 18:18:01 +00:00
refractionpcsx2 682797c54b GameDB: Re-remove Half-Pixel Offset from Mercenaries.
Left commented out so we don't make the same mistake again.
2022-11-05 14:46:10 +00:00
refractionpcsx2 2221a12950 GS-HW: GetOutput loop on 2048 and restrict height. 2022-11-05 04:57:44 +00:00
refractionpcsx2 e2cdcd094a GameDB: Add upscaling fixes for many games. 2022-11-05 03:45:31 +00:00
refractionpcsx2 71b0d9cc38 GameDB: Add COP2 patch for Donald Duck Goin' Quackers 2022-11-04 23:12:25 +00:00
refractionpcsx2 808fadd061 GameDB: Add COP2 patch for Donald Duck - Quack Attack 2022-11-04 19:44:53 +00:00
Mrlinkwiiandrefractionpcsx2 760d349af1 GameDB:Fix minor typos 2022-11-04 19:44:41 +00:00
refractionpcsx2 6b2a20231d SPU: On config change don't reinit sample rate.
Also fix up some other samplerate related things and turn the soundtouch pointer in to a unique pointer.
2022-11-04 16:45:26 +00:00
refractionpcsx2 975aac5a00 GS-HW: Further restrict CLUT width to 8, 16, 32, 64 2022-11-04 16:45:07 +00:00
refractionpcsx2 f6909d0ea9 GameDB: Add autoflush to Tales of the Abyss. Fixes lighting post 2022-11-04 02:14:57 +00:00
Mrlinkwiiandrefractionpcsx2 88ee6659b2 GameDB: some minor corrections 2022-11-03 23:35:14 +00:00
dependabot[bot]andrefractionpcsx2 3e878f5124 Bump mathieudutour/github-tag-action from 6.0 to 6.1
Bumps [mathieudutour/github-tag-action](https://github.com/mathieudutour/github-tag-action) from 6.0 to 6.1.
- [Release notes](https://github.com/mathieudutour/github-tag-action/releases)
- [Commits](https://github.com/mathieudutour/github-tag-action/compare/v6.0...v6.1)

---
updated-dependencies:
- dependency-name: mathieudutour/github-tag-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-03 21:50:57 +00:00
Mrlinkwiiandrefractionpcsx2 c32c4c1e46 GameDB: disable MTVU & instantVU for K1 series games 2022-11-03 19:08:15 +00:00
refractionpcsx2 1e526097f6 GameDB: Add upscaling fixes for Super Trucks (Racing) 2022-11-03 19:07:08 +00:00
refractionpcsx2 7c728c4ae1 GameDB: HPO for Destruction Derby Arenas 2022-11-03 19:07:08 +00:00
refractionpcsx2 87aa7bbb76 GS: Restrict age of targets for GS Download invalidation. 2022-11-03 15:26:25 +00:00
Mrlinkwiiandrefractionpcsx2 729fd3cebf GameDB: add upscaling fixes to F1 2001/2002 and F1 Career Challenge 2022-11-03 10:26:09 +00:00
suXinandrefractionpcsx2 a9d7164b58 GameDB: WRC Rally Evolved - Fix rare bug causing player to respawn unexpectedly 2022-11-03 10:17:41 +00:00
RedDevilusandrefractionpcsx2 8a9a7f0858 GameDB: Silent Hill 4
Silent Hill 4: Fixes invisible wall in front of the door leading to East 3F in the 2nd visit of Apartment world preventing Eileen's Nurse Outfit. (accidentally did Resident Evil 4 instead)
2022-11-03 00:38:05 +00:00
RedDevilusandrefractionpcsx2 f02aa252b7 GameDB: Resident Evil 4 (BioHazard 4) + Umisho
Resident Evil 4 / BioHazard 4: Fixes invisible wall in front of the door leading to East 3F in the 2nd visit of Apartment world preventing Eileen's Nurse Outfit.

Umisho: Minor upscaling line issue fix
2022-11-02 23:12:30 +00:00
refractionpcsx2 6103d07d07 GS: Restrict CLUT SW draw widths to multiples of 8
code does 0-7 for points (inclusive) and 0-8 for anything else (exclusive)
2022-11-02 12:17:29 +00:00
Mrlinkwiiandrefractionpcsx2 66f166909e GameDB: add missing serial 2022-11-01 21:51:05 +00:00
Fothsidandrefractionpcsx2 03f7002711 GS/TextureCache: remove an unnecessary TBW check 2022-11-01 21:25:46 +00:00
lightningterror ff58de2d8c cmake: comment out config guide.
Outdated, will be re added once guides are updated.
2022-11-01 16:06:32 +01:00
lightningterror 9a4585d438 gui-wx: Comment out config guide code.
Outdated.
2022-11-01 16:06:32 +01:00
lightningterror 81800c5a4d Documentation: Remove config guide from dev builds.
Outdated/irrelevant mostly.
2022-11-01 16:06:32 +01:00
Fothsidandrefractionpcsx2 e2e9249d40 GS: Check memory overlaps with targets for GS downloads 2022-11-01 10:55:02 +00:00
Connor McLaughlinandrefractionpcsx2 9cc852a097 GS/Vulkan: Copy entire target when ds == tex
Also for DX12. Shadow Hearts 3 does a downsample, and we don't copy enough
if we limit to the render area.

Really, the texture cache should be handling this. But since we have the
target height more correct now, the perf hit shouldn't be much.
2022-11-01 09:55:17 +00:00
Connor McLaughlinandrefractionpcsx2 0b98c7a352 D3D12HostDisplay: Fix defaulting to vsync off 2022-11-01 09:47:24 +00:00
Connor McLaughlinandrefractionpcsx2 4463531f1e FullscreenUI: Various improvements 2022-11-01 09:47:24 +00:00
JordanTheToasterandrefractionpcsx2 61ed160881 GameDB: Add HPO Normal to Indiana Jones SOK
Adds HPO Normal to Indiana Jones Staff of Kings.
2022-10-31 23:36:08 +00:00
refractionpcsx2 fd6b0d07fb GS: Fix small config refresh bug. 2022-10-31 21:04:18 +00:00
JordanTheToasterandrefractionpcsx2 d92b6648ac GameDB: Add HPO Normal to WRC 4 and VU Round Nearest to GH 5
Adds HPO Normal to WRC 4 to fix minor ghosting on objects and VU Round Mode Nearest to GH 5 to fix SPS and console log spamming size.
2022-10-31 20:57:01 +00:00
PCSX2 Botandlightningterror ae71427b91 PAD: Update to latest controller database. 2022-10-31 21:04:25 +01:00
xujibbsandGitHub 08a9c052d5 Qt: Add translate tag to shutdown message (#7302) 2022-10-31 12:05:47 +00:00
refractionpcsx2 865c103d42 GameDB: Add SW CLUT draws to Ridge Racer, Fixes car textures.
Warning: This is possibly a misdetection, so it might break later on.
2022-10-31 00:05:09 +00:00
refractionpcsx2 fc87b54439 GS-HW: Fix bugs in CLUT draw heuristics, fixes up Driver Parallel Lines 2022-10-30 23:58:11 +00:00
refractionpcsx2 fe53a3f52c GSHW: Ignore recursive draws in CLUT heuristics. 2022-10-30 20:39:34 +00:00
refractionpcsx2 72e8c66879 GameDB: Add CLUT renderer + other fixes 2022-10-30 14:46:11 +00:00
refractionpcsx2 bc2f576b30 GS-HW: SW Render CLUT draws 2022-10-30 14:46:11 +00:00
Mrlinkwiiandrefractionpcsx2 614c535f5e Gamedb: add WRC4 patch to NTSC-J version 2022-10-30 13:12:29 +00:00
JordanTheToasterandrefractionpcsx2 92b5a6e381 GameDB: Add fixes and missing fixes to Ape Escape 3
Adds HPO Special Texture and Autoflush to Ape Escape 3 as well as adding missing fixes to other versions of Ape Escape 3.
2022-10-29 18:33:44 +01:00
refractionpcsx2 c6924ccaeb HW-TC: Keep old frames usable a bit longer.
The old value was a bit too violent on loading screens which didn't update very frequently (Mission Impossible), this new value works pretty well with both.
2022-10-28 23:04:56 +01:00
Ganael Laplancheandlightningterror aa59547af7 build: Fix build on FreeBSD
- ftruncate64() does not exist on FreeBSD
- add missing environ(7) declaration
2022-10-28 13:25:49 +02:00
Ganael Laplancheandlightningterror 67f1cd4e15 Fix shm_open(3) call on FreeBSD
On FreeBSD, shm_open(3) requires name to start with a '/', else EINVAL
is returned.

See: https://www.freebsd.org/cgi/man.cgi?shm_open
2022-10-28 13:25:49 +02:00
TheLastRarandlightningterror 6ad98e2c70 DEV9: Sockets: Fix UDP FixedPort 2022-10-27 23:53:37 +02:00
TheLastRarandlightningterror 0ee28f3433 DEV9: Sockets: Log correct UDP port 2022-10-27 23:53:37 +02:00
TheLastRarandlightningterror 25107bd2db DEV9: Fix setting response code 2022-10-27 23:53:37 +02:00
TheLastRarandlightningterror 304f260cff DEV9: Fix DNS Internal mode acting as Auto mode 2022-10-27 23:53:37 +02:00
Mrlinkwiiandrefractionpcsx2 9bcf4d2571 Gamedb :add upscaling fixes to 'Kingdom Hearts II' 2022-10-27 15:28:22 +01:00
GeordieandGitHub e129a06436 MemoryCard: Fix a crash that happens when copying from one card to a folder memory card via BIOS. (#6746)
This fixes a crash that happens if you attempt to copy from one memory card to a formatted folder memory card.
2022-10-26 18:30:44 +02:00
lightningterror c99714dbb2 GSClut: Fix Wsign-compare warning. 2022-10-26 13:54:14 +02:00
lightningterror 8771d3bc19 GS-hw: Use GSVector for rb ga masks in texture shuffle. 2022-10-26 13:16:49 +02:00
Mrlinkwiiandrefractionpcsx2 e5964ae35b GS-hw: purge DBZBT3 upscaling CRC hack 2022-10-25 10:14:38 +01:00
JordanTheToasterandrefractionpcsx2 218b792e73 GameDB: Add VUSyncHack to Twisted Metal Head On
Adds VUSyncHack to Twisted Metal Head On to fix the black doors issue.
2022-10-25 00:36:28 +01:00
Mrlinkwiiandrefractionpcsx2 0b253b07b2 Gamedb: fix 'Fatal Fury Battle Archives Vol.1' name 2022-10-24 21:43:16 +01:00
PCSX2 Botandlightningterror be85ed3645 PAD: Update to latest controller database. 2022-10-24 18:10:20 +02:00
JordanTheToasterandlightningterror 9868abe1b1 UI: Minor text fixes
Fixes flipped text from the Spin GPU PR.
2022-10-24 16:56:27 +02:00
lightningterror cdb886a454 GS-hw: Implement missing st_int shader bit.
Was causing bad shader errors in GT4.
2022-10-24 16:22:44 +02:00
TellowKrinkleandrefractionpcsx2 ac1f31f2cd GS:HW: Add option to spin CPU during readbacks 2022-10-24 14:33:17 +01:00
TellowKrinkleandrefractionpcsx2 89dd7f19ef Misc: Improve pause speed measurements
Avoids issues with cores being clocked down during the measurement
2022-10-24 14:33:17 +01:00
TellowKrinkleandrefractionpcsx2 923b0817ce GS:Vk: Add option to spin GPU during readbacks 2022-10-24 14:33:17 +01:00
TellowKrinkleandrefractionpcsx2 4c9981f3c8 Common:Vk: Move command buffer completion processing to separate function 2022-10-24 14:33:17 +01:00
TellowKrinkleandrefractionpcsx2 0ef469f3b5 Common:Vk: Load VK_EXT_calibrated_timestamps 2022-10-24 14:33:17 +01:00
TellowKrinkleandrefractionpcsx2 73044dffed GS:MTL: Add option to spin GPU during readbacks 2022-10-24 14:33:17 +01:00
TellowKrinkleandrefractionpcsx2 ea35619a78 Common: Add class for spinning GPUs 2022-10-24 14:33:17 +01:00
TheLastRarandrefractionpcsx2 8280292fb4 DEV9: Add per game host list support 2022-10-23 22:20:39 +01:00
Connor McLaughlinandrefractionpcsx2 dc8cdc95d0 GSRunner: Write log and disable cache in parallel runs 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 5e9710a8c6 Qt: Support overriding log file on command line 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 c404bd9f17 GSRunner: Support running surfaceless 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 61de98d651 Vulkan: Support running surfaceless 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 bf2575c3c9 GL/ContextWGL: Fix running surfaceless 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 f5e64232c9 GSRunner: Strip spaces from filenames 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 9daedf6f09 x86/microVU: Fix last block comparison for AVX2 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 dad1e659a5 Achievements: Disable challenge mode on shutdown 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 0a8547a692 Qt: Fix main window briefly showing when exiting game in FSUI 2022-10-22 23:19:54 +01:00
Connor McLaughlinandrefractionpcsx2 5647ca7f08 Qt: Add play time tracking based on serials 2022-10-22 11:08:23 +01:00
Connor McLaughlinandrefractionpcsx2 a3b3edb565 Qt: Add interface section to per-game settings 2022-10-22 10:13:40 +01:00
Connor McLaughlinandrefractionpcsx2 fb9c9cb172 Qt: Don't load confirm shutdown/render separate/etc from base 2022-10-22 10:13:40 +01:00
Connor McLaughlinandrefractionpcsx2 2815bd177c GS/HW: Fix RGB/A splitting on accumulation blend with DSB off 2022-10-22 10:13:30 +01:00
refractionpcsx2 7aa05c08f1 EEJIT/COP2: Remove redundant instruction/allocation 2022-10-22 03:42:31 +01:00
refractionpcsx2 112ba57729 EE/JIT: Flush Rt on LDR/LDL before write 2022-10-22 03:42:31 +01:00
refractionpcsx2 bdac7672b7 SPU2: Move ADMA clear to ADMA disable.
Fix bug with errantly setting data size if there isn't any.
2022-10-22 01:51:22 +01:00
JordanTheToasterandrefractionpcsx2 09a49cfaa0 GameDB: Add mipmapping and trilinear filtering to Black
Adds Mipmapping Full and Trilinear (PS2) to Black.
2022-10-21 13:16:52 +01:00
refractionpcsx2 08cac6affd CDVD: Partial revert change from #5142 keep read state when buffering. 2022-10-21 12:41:11 +01:00
refractionpcsx2 ade8517429 GameDB: Remove SW switch for Grandia Xtreme + Update Simpsons GSHwHacks 2022-10-21 12:02:53 +01:00
refractionpcsx2 c9826cb26a GS: Only allow recently updated frames for display. 2022-10-21 12:02:53 +01:00
refractionpcsx2 3f764e3122 Qt: Fix updating settings when bios changed 2022-10-21 12:02:23 +01:00
refractionpcsx2 9d29287c02 Qt: Update emuthread settings on blockdump directory change 2022-10-21 12:02:23 +01:00
refractionpcsx2 b9cdd452df GameDB: Remove Dragon Quest & Final Fantasy in Itadaki Street patch 2022-10-21 11:04:45 +01:00
refractionpcsx2 32d1105833 GS: Improve upload TEX overwrite detection 2022-10-21 11:04:45 +01:00
JordanTheToasterandrefractionpcsx2 d84d4cec4f GameDB: Add autoflush to Suffering TTB
Adds Autoflush to the suffering ties that bind.
2022-10-21 01:31:31 +01:00
Connor McLaughlinandrefractionpcsx2 e9a61c24df GSRunner: Add standalone GS runner/dumper 2022-10-20 19:43:29 +01:00
Connor McLaughlinandrefractionpcsx2 5ffcbad18b GSDumpReplayer: Support no-looping/frame number queries 2022-10-20 19:43:29 +01:00
Connor McLaughlinandrefractionpcsx2 e7c4894833 Common: Add MemorySettingsInterface 2022-10-20 19:43:29 +01:00
Ty Lamontagneandrefractionpcsx2 3289cd1e2b Move some IPU logging to systrace instead of devcon
My code emits 64 bit reads for some reason, and it's slowing me down.
2022-10-20 18:39:18 +01:00
refractionpcsx2 4127253650 GS/State: Correct CLUT invalidation range check 2022-10-20 14:57:30 +01:00
Connor McLaughlinandrefractionpcsx2 2c55cce6ba GS/TextureCache: Use Inside() for checking display target
The existing code was adding however many pages the framebuffer crossed unconditionally,
when practically this last row will only be read when the height isn't page-aligned.
2022-10-20 14:57:30 +01:00
Silentandrefractionpcsx2 633eb45011 vs: Enable Function Level Linking solution-wide and AVX2 for Common project
Shrinks the AVX2 Qt binary by ~2.3MB.
2022-10-20 12:10:17 +01:00
TellowKrinkleandrefractionpcsx2 65aeeba567 GHActions: Migrate to new variable output system 2022-10-20 09:30:00 +01:00
TellowKrinkleandtellowkrinkle f37fd29fd0 CMake:Windows: Add install step 2022-10-19 15:50:43 -05:00
TellowKrinkleandtellowkrinkle 310ed9af0d GHActions: Add CMake Qt build 2022-10-19 15:50:43 -05:00
TellowKrinkleandtellowkrinkle 4e4ffa6526 CMake: Windows Qt build support 2022-10-19 15:50:43 -05:00
TellowKrinkleandtellowkrinkle 8975f2d92c Qt: Add comment on ODR violation workaround 2022-10-19 15:50:43 -05:00
Connor McLaughlinandlightningterror ddf839beb0 Achievements: Rework challenge mode enabling
Fixes enabling hardcore mode per-game not having any effect.
2022-10-19 18:35:08 +02:00
Connor McLaughlinandlightningterror 53bd98394b FullscreenUI: Fix achievements/lb hotkey running on EE thread 2022-10-19 18:35:08 +02:00
Connor McLaughlinandrefractionpcsx2 84bea96941 GS: CRC hack for Black 2022-10-19 17:17:46 +01:00
lightningterrorandrefractionpcsx2 4470379dfb GameDB: Add Round Sprite Half to Ikki Tousen.
Aligns bloom effect.
2022-10-19 10:14:27 +01:00
lightningterrorandrefractionpcsx2 f727561553 GS-hw: Remove Ikki Tousen crc hack.
Upscaling hack, upscaling fixes in gamedb will deal with it.
2022-10-19 10:14:27 +01:00
Connor McLaughlinandrefractionpcsx2 e6dbd55644 Qt: Use vsync when any FSUI window is open
Fixes high GPU usage when pause menu is opened. Previously, it was fine
if you started from big picture mode, but not if you invoked it by
opening the menu.
2022-10-19 10:12:44 +01:00
Ty Lamontagneandrefractionpcsx2 0df6fda9e8 Cubeb: Fix logging comparison, causing verbose spam 2022-10-19 10:12:17 +01:00
Connor McLaughlinandrefractionpcsx2 1d58f59190 GS/Vulkan: Fix condition for skipping first barrier
Use the image layout instead of start-of-render-pass, because the image
may already be in general, or it could be restarting the RP from a
render area change.
2022-10-19 10:11:07 +01:00
lightningterror a30a41c2cc GS-wx: Misc fixes.
Add Hardware Download Mode option.
Remove Disable Hardware Readbacks.
Set dump decompression to LZMA.
And some other misc fixes.
2022-10-19 00:16:26 +02:00
JordanTheToasterandlightningterror 7a82b941cb ImGuiOverlays: Add Texture in RT
Adds Texture in RT to the imgui overlay.
2022-10-18 21:01:24 +02:00
JordanTheToasterandrefractionpcsx2 480e126437 GameDB: Correct Big Game Hunter name
Corrects the name of SLUS-21021 and SLUS-21011.
2022-10-18 19:52:03 +01:00
refractionpcsx2 92d43d042d GameDB: Add HW/Upscale fixes for King's Field IV 2022-10-18 19:34:37 +01:00
lightningterror f2b172738f GS-wx: Add show settings and show inputs options to osd. 2022-10-18 18:26:32 +02:00
refractionpcsx2 4fe1217a69 SPU: Clamp final volume in the right place. 2022-10-18 16:47:43 +01:00
Connor McLaughlinandlightningterror fa82fc49bb GS/Vulkan: Skip first barrier when starting pass 2022-10-18 17:34:15 +02:00
JordanTheToasterandlightningterror 5d1e340cbb GameDB: Add " World Soccer Winning Eleven 2012" missing entry
Adds a missing entry in the DB.
2022-10-18 17:10:19 +02:00
lightningterror abcbdc4a25 GS-hw: Further improve how we handle blend mix 1.
Compensate slightly for Cd*(As + 1) - Cs*As.
Try to compensate a bit with substracting 1 (0.00392) * (Alpha + 1) from Cs.
The initial factor we chose is 1 (0.00392) as that is the minimum color Cd can be, then we multiply by alpha to get the minimum blended value it can be.
2022-10-18 15:20:41 +02:00
Florin9doiandrefractionpcsx2 8fbb1e5565 BIOS: Map the entire ROM1 file to PS2 memory
EROM is part of ROM1, its exact location vary and can't be predicted
2022-10-18 10:04:52 +01:00
JordanTheToasterandrefractionpcsx2 149a08914e GameDB: Copy missing "Game ni Nattayo! Dokuro-chan" patch
Copys over the existing patch that was missing from the limited edition version.
2022-10-18 10:03:35 +01:00
Mrlinkwiiandrefractionpcsx2 f5c51f7cf7 GameDB: add missing patch to Asobi ni Iku yo! Chikyuu Pinch no Kon'yaku Sengen 2022-10-18 10:03:17 +01:00
RedDevilusandrefractionpcsx2 280b3c66eb GameDB: Kaido/Xtreme Racer upscaling + comments
Adding upscaling fixes for vertical lines for Kaido / Tokyo Xtreme Racer by Developer Genki and Publisher Crave. Needs check-up if other fixes are needed as well.
2022-10-17 23:56:41 +01:00
PCSX2 Botandlightningterror 3a3732a6c6 PAD: Update to latest controller database. 2022-10-17 18:08:41 +02:00
lightningterror 2093c19127 GS: Adjust default renderer for vendors on windows.
AMD, feature level 12.0 and higher pick Vulkan by default.
Intel, feature level 12.0 and higher, pick OpenGL by default.
2022-10-17 16:36:46 +02:00
Connor McLaughlinandrefractionpcsx2 c2823aae39 GS: Fix fractional scaling in GL/Vulkan 2022-10-17 15:26:01 +01:00
Connor McLaughlinandrefractionpcsx2 ec1a896795 GS/TextureCache: Partially invalidate overlapping targets with tex-in-rt 2022-10-17 10:47:13 +01:00
Mrlinkwiiandrefractionpcsx2 a46964a258 Mac: add PCSX2 to Launchpad Game Category 2022-10-17 09:45:07 +01:00
lightningterror b4036f44f1 GS-hw: Disable blend mix on colclip.
Regression, should be disabled.
2022-10-17 10:29:33 +02:00
TellowKrinkleandlightningterror 1ad6605dfb GS:HW: Remove comment on rgba to 8i only-blue optimization
Doesn't seem to improve anything anymore (GPUs do this with csel now anyways, it's like 5 instructions with no divergence)
2022-10-17 10:28:27 +02:00
TellowKrinkleandlightningterror c6add663f8 GS:HW: Clean up ps_convert_rgba_8i 2022-10-17 10:28:27 +02:00
TellowKrinkleandtellowkrinkle 1ac081ef4c Common: Make GL::Context::Create use gsl::span 2022-10-16 19:24:45 -05:00
TellowKrinkleandtellowkrinkle 074e90d046 3rdparty: Add GSL
Version 4.0.0 (a3534567187d2edc428efd3f13466ff75fe5805c)
2022-10-16 19:24:45 -05:00
TellowKrinkleandtellowkrinkle a2c3050c51 Common: Formatting 2022-10-16 19:24:45 -05:00
JordanTheToasterandrefractionpcsx2 de60209e2b GameDB: Enable Paltex for Zone of The Enders
Improves FPS and drastically reduces the size of the hash cache in game.
2022-10-16 21:38:16 +01:00
Mrlinkwiiandrefractionpcsx2 d385480b52 GameDB: add fixes for Eternal Ring and Spongebob SquarePants Featuring Nicktoons - Globs of Doom 2022-10-16 15:58:54 +01:00
lightningterror 6b1cea6c91 FullscreenUI: Fix Wunused-variable warning. 2022-10-16 16:14:49 +02:00
lightningterror d2b5f86639 Qt: Fix Wunused-variable warning. 2022-10-16 16:14:25 +02:00
Connor McLaughlinandrefractionpcsx2 e8877daca3 Qt: Register for device notifications on Windows
That way we know when a controller is connected/disconnected, and don't
have to poll unconnected XInput controllers.
2022-10-16 14:54:38 +01:00
Connor McLaughlinandrefractionpcsx2 b9dffcb069 Qt: Add DInput input source 2022-10-16 14:54:38 +01:00
Connor McLaughlinandrefractionpcsx2 bcd19dd0f5 Qt: Add Host::GetTopLevelWindowInfo() 2022-10-16 14:54:38 +01:00
Connor McLaughlinandlightningterror 48926a7ec4 x86/iR5900: Fix quadword stores on Linux
Linux counts vector and GPR registers separately for which register
they get passed in when calling functions.

Windows uses the argument position.
2022-10-16 14:41:33 +02:00
TellowKrinkleandrefractionpcsx2 8981572674 GS:HW: blend_mix doesn't get you fast hdr
It didn't before either, it just accidentally turned on full barriers
2022-10-16 05:09:02 +01:00
Connor McLaughlinandrefractionpcsx2 f836fe2056 GS/Vulkan: Ensure we don't leave a bound texture in copy state
Causes the validation layer to get angry, even though it's not used.
2022-10-15 17:42:51 +01:00
Connor McLaughlinandrefractionpcsx2 1067714c2c PAD/Qt: Compute deadzone as circular instead of square 2022-10-15 17:38:09 +01:00
Connor McLaughlinandrefractionpcsx2 6b0564d6e4 Qt: Add automatic updater for Linux 2022-10-15 17:37:49 +01:00
Connor McLaughlinandrefractionpcsx2 6c17f7ad49 GS: Support fractional upscale 2022-10-15 17:37:35 +01:00
Connor McLaughlinandrefractionpcsx2 44bad588b4 GS: Unify shader cache versions across renderers
It's not often that we make a change unique to one API. This way, you
only have to bump the version in one location, instead of four.
2022-10-15 15:17:06 +01:00
Connor McLaughlinandrefractionpcsx2 44c8974aba GS: Set vsync based on host decision
Fixes bug where after changing settings in the big picture UI, if you
didn't have a game running, it would turn off vsync, making GPU go brr.

Also cleans up HostDisplay a bit, removing redundant parameters.
2022-10-15 15:17:06 +01:00
Connor McLaughlinandrefractionpcsx2 6a1eb231dd ImGuiOverlays: Add hardware download mode to settings OSD 2022-10-15 15:16:50 +01:00
lightningterrorandrefractionpcsx2 39ab409970 GameDB: Add Full mipmap + Trilinear ps2 on GT4.
Better accurately render ground textures, makes it match sw renderer.
2022-10-15 15:16:34 +01:00
Connor McLaughlinandrefractionpcsx2 cb1817f440 GS: Add hardware download mode option 2022-10-15 10:18:31 +01:00
Connor McLaughlinandrefractionpcsx2 0b09c259aa Qt: Add input and settings overlays 2022-10-15 10:11:17 +01:00
Connor McLaughlinandrefractionpcsx2 d446e40741 System: Remove/move out a bunch more leftover stuff from wx
The exceptions are particularly nasty, because there's nothing which
catches them.
2022-10-14 22:24:42 +01:00
Connor McLaughlinandrefractionpcsx2 00bcb4cf02 System: Revamp memory allocation
Guest memory is now mapped into a shared memory/file mapping, for use
with fastmem.

64-bit and 128-bit arguments are passed by register/value instead of by
reference/address.

LDL/LDR/SDL/SDR now use 64-bit GPRs instead of SSE.
2022-10-14 22:24:42 +01:00
Connor McLaughlinandrefractionpcsx2 92ad6f3baf x86emitter: Fix missing W REX bit for movq reg, xmm 2022-10-14 22:24:42 +01:00
RedPanda4552andrefractionpcsx2 fb9c38b75f Qt: Add dialog for memory card conversion 2022-10-14 21:56:41 +01:00
Connor McLaughlinandrefractionpcsx2 ab295f0f10 x86/microVU: Add a reference list for quick block lookups
This way, we can pack 8 entries in a single cache line, instead of one.
2022-10-14 20:54:39 +01:00
Connor McLaughlinandrefractionpcsx2 197d4d1c81 x86/microVU: Use AVX2 for full block comparisons 2022-10-14 20:54:39 +01:00
Connor McLaughlinandrefractionpcsx2 bf95193d5b x86/microVU: Use 64-bit comparisons for quick lookup 2022-10-14 20:54:39 +01:00
Connor McLaughlinandrefractionpcsx2 375c0a02bb x86emitter: Add some AVX/AVX2 instructions and YMM registers 2022-10-14 20:54:39 +01:00
Mrlinkwiiandrefractionpcsx2 ac10e00d7c Gamedb : add upscaling fixed to Call of duty 3 2022-10-14 20:28:06 +01:00
Ganael LaplancheandGitHub f5498a4660 Build: Fix build with wx 3.1 on FreeBSD (#7178) 2022-10-14 10:55:55 +01:00
Connor McLaughlinandrefractionpcsx2 95968c7e0e CommonHotkeys: Fix target speed going below zero
Also clamps to 100% for challenge mode.
2022-10-14 10:52:27 +01:00
boringhexiandGitHub f59030ecaf GameDB: 'Gitaroo Man' patches and fixes (#7184) 2022-10-14 10:50:15 +01:00
Connor McLaughlinandrefractionpcsx2 da7f068d5d FullscreenUI: Deadlock fix and add reset confirm for HC enable 2022-10-13 09:03:13 +01:00
Mrlinkwiiandrefractionpcsx2 e845c59229 Gamedb: miscellaneous missing entries 2022-10-12 11:17:14 +01:00
refractionpcsx2 c391e84451 GS: Only TEXFLUSH if it's an Auto Flush draw. 2022-10-11 18:45:32 +01:00
TellowKrinkleandlightningterror 9b5dd92dad GS:HW: Use 16-bit unorm for HDR 2022-10-11 18:17:27 +02:00
TellowKrinkleandlightningterror 4a7539cd06 GS:HW: Rename FloatColor to HDRColor
It will soon be not a float
2022-10-11 18:17:27 +02:00
refractionpcsx2 e8a021e1b0 GS: Add flush reason to draw call vertex dumps 2022-10-11 17:16:18 +01:00
RedDevilusandrefractionpcsx2 8b92872c1f Qt: Changing Cheevos URL color
At the moment it uses a dark blue color which looks fine on light themes but hurts my eyes on the darker themes, reminds me of the old 1.6 console dark mode

Making it currently a bit lighter blue which should fit all the themes, in the future we could make it follow the link color.
2022-10-11 13:14:25 +01:00
Connor McLaughlinandrefractionpcsx2 6f99ac676e INISettingsInterface: Write changes atomically 2022-10-11 12:57:27 +01:00
lightningterror 7433cec2c4 GameDB: Add HPO normal to remaining regions of Wallace & Gromit - The Curse of the Were-Rabbit.
Names were different so didn't pick them up during search, also make the names match.
2022-10-11 01:52:25 +02:00
lightningterror a1e5ce246b GameDB: Add HPO Special to Wallace & Gromit - The Curse of the Were-Rabbit.
Fixes misalignment/bloom when upscaling.
2022-10-11 01:37:45 +02:00
lightningterror 97ba76ab47 GameDB: Add trilinear PS2 and change mipmap from Basic to Fast to Hulk The Ultimate Destruction
Further fixes textures to match sw renderers.
2022-10-11 01:29:58 +02:00
lightningterror 866dee7cc2 GameDB: Adjust HPO from Normal to Special for Shadow of Rome and Onimusha Dawn of Dreams.
Issues with HPO special were the clamp optimizations.
2022-10-11 01:08:31 +02:00
lightningterror 4f1143420c GS-hw: Fully purge Shadow of Rome crc hacks.
Issue with upscaling and hpo special was clamp optimizations.
2022-10-11 00:56:02 +02:00
lightningterror 702aefa43e GS-hw: Disable clamp more optimizations for now.
We currently crop off the rightmost and bottommost pixel when upscaling clamps, until the issue is properly solved we should keep this disabled as it breaks many games when upscaling.
2022-10-11 00:43:23 +02:00
PCSX2 Botandlightningterror 86ca20403e PAD: Update to latest controller database. 2022-10-10 18:05:12 +02:00
RedDevilusandrefractionpcsx2 356b5c1750 Qt: Consistent save state list in big picture
In the WX days we had savestate 0-9 where 0 was the first. Then Qt came around where savestate 0-10 existed for Big Picture and 1-10 for the main listing this can cause headaches where you cycle through savestates or just save to the current slot 0 and it doesn't show up in the main window.
2022-10-10 14:06:59 +01:00
Mrlinkwiiandrefractionpcsx2 37c89ffba3 gamedb: add autoflush to 'The Simpsons: Hit & Run.' 2022-10-09 21:01:40 +01:00
lightningterror 4a83efcd61 GS-hw: Cleanup GSHWHack.cpp
Declare functions noexcept, initialize variables.
2022-10-09 21:10:20 +02:00
lightningterror 871308cf25 GS-hw: Remove condition to enable upscaling hacks on Aggressive crc.
Not really needed, favor accuracy.
2022-10-09 21:10:20 +02:00
lightningterror 90f1ea7896 GS-hw: No need to check for coverage when getting alpha value.
We already set the alpha min max value to 128 if coverage is used.
2022-10-09 17:51:33 +02:00
lightningterror 1c308b2710 GS: When CoverageAlpha is used set Alpha min max to 128. 2022-10-09 17:51:33 +02:00
lightningterror 5227bc9167 GS-hw: Add missing stencil buffer check for fba or coverage alpha DATE. 2022-10-09 17:51:33 +02:00
refractionpcsx2 4f93ee29e6 GS: Remove no longer needed logging. 2022-10-09 13:37:00 +01:00
Connor McLaughlinandlightningterror 07a51589cb GameDB: Normalize HW fixes for Xenosaga Episode II 2022-10-09 09:32:28 +02:00
RedDevilusandlightningterror 67847c9485 Qt: Amendment for Turbo naming
PCSX2 uses the Fast Forward naming in the hotkeys but DuckStation uses Turbo for a similar function.

Makes it easier to see what the hotkey is for.
2022-10-09 09:30:36 +02:00
refractionpcsx2 96071e157a GS: Modify clamp behaviour on large specified texture sizes
Add temp logging
2022-10-09 06:25:22 +01:00
refractionpcsx2 f70da4b33e GS: Handle higher TH/TW for STQ calculation 2022-10-09 06:25:22 +01:00
refractionpcsx2 92cd6e8435 GS: Fix DX shader error 2022-10-09 04:53:18 +01:00
TellowKrinkleandrefractionpcsx2 0637682eb0 GS:HW: Properly handle fbmask of negative values
Previously was possible with blending and colclip, but now more common with the new hdr algorithm
2022-10-09 04:06:59 +01:00
TellowKrinkleandrefractionpcsx2 af1888b21a GHActions:macOS: Remove unused dependencies 2022-10-08 22:41:59 +01:00
TellowKrinkleandrefractionpcsx2 fca61d68b0 GHActions:MacOS: Disable Qt gssapi support
Qt's build script picks up gssapi_krb5.dylib instead of GSS.framework on some MacOS SDKs, failing the build.  We don't need GSS, so disable it instead of patching
2022-10-08 22:41:59 +01:00
TellowKrinkleandrefractionpcsx2 954e9fc7c1 CMake: Prevent finding Mono.framework libpng 2022-10-08 22:41:59 +01:00
refractionpcsx2 9750cfe6bf GS: Fixes for flushes from PR #6389 2022-10-08 21:10:13 +01:00
Connor McLaughlinandrefractionpcsx2 1910c8fc0f GS/HW: Only allocate as many mip levels as present
This prevents any possibility of sampling undefined or garbage/reused
texture data from levels which aren't used by the current draw.

And a tiny bit of VRAM. But nothing really measurable.

Also fixes a bug in Vulkan where a copied texture can get mip-generated
in the wrong command buffer when using basic mipmapping.
2022-10-08 19:42:45 +01:00
lightningterror 7f9932129d FullscreenUI: Remove unused variables. 2022-10-08 20:16:31 +02:00
Connor McLaughlinandrefractionpcsx2 8947c0d2e7 Qt: Fix primed indicator not being disabled when achievements off 2022-10-08 14:18:35 +01:00
Connor McLaughlinandrefractionpcsx2 48015d3f43 Achievements: Append notifications downwards not upwards 2022-10-08 14:18:35 +01:00
Connor McLaughlinandrefractionpcsx2 74ffdca614 Achievements: Save submitted time from API in leaderboards 2022-10-08 14:18:35 +01:00
Connor McLaughlinandrefractionpcsx2 2ae3c6bf29 Achievements: Check for nulls in API responses
rc_json_get_string() stores NULL if the server literally sends "null".
2022-10-08 14:18:35 +01:00
Connor McLaughlinandrefractionpcsx2 28e33e1883 Achievements: Reapply settings on HC enable 2022-10-08 14:18:35 +01:00
Connor McLaughlinandrefractionpcsx2 9615120586 VulkanHostDisplay: Fix crash when driver uses large preferred upload stride 2022-10-08 14:18:35 +01:00
lightningterror 3d557be918 GS-hw: Adjust Shadow of Rome crc hacks.
Remove some unneeded crc hacks while making leftover upscale only.
2022-10-08 14:49:19 +02:00
icup321andrefractionpcsx2 b166b1a383 GameDB: Fix missing splash logos in Krome games
Also fixes water textures in TY 2 & 3.
2022-10-08 13:17:51 +01:00
Connor McLaughlinandrefractionpcsx2 905e573520 Qt: Fix error writing config on first launch 2022-10-08 13:17:34 +01:00
Connor McLaughlinandlightningterror 15b91fb6a4 Qt: Drop libsamplerate dependency for Qt+MSVC
It's only used by USB/WASAPI, which doesn't exist in Qt.
2022-10-08 12:50:10 +02:00
Connor McLaughlinandlightningterror 2c64c729bf VMManager: Remove unused variable 2022-10-08 12:49:00 +02:00
refractionpcsx2 2ddc7897e0 WX: Backport Resamplebox patch to fix GSDump previews in vs2022 2022-10-08 05:41:28 +01:00
icup321andrefractionpcsx2 e359cc5da9 GameDB: Fix ghosting in BlitzTech engine games
Also fixes a few game title issues.
2022-10-07 21:32:01 +01:00
TellowKrinkleandlightningterror 73ae9f8879 GS:HW: Make HDR algorithm more float-precision-friendly
- Use whole numbers instead of 255ths
- Use range -128 - 127 instead of 0 - 255 for accumulation blends
2022-10-07 20:44:53 +02:00
Connor McLaughlinandrefractionpcsx2 7ea8b983d4 CI: Switch from libcurl4-gnutls-dev to libcurl4-openssl-dev
Hopefully fix the Linux AppImage not finding certificates on Debian.
2022-10-07 11:28:16 +01:00
refractionpcsx2 4b652e6878 GameList: remove playlists 2022-10-06 21:57:03 +01:00
Mrlinkwiiandrefractionpcsx2 90c541d117 Gamedb: add EE rounding to 'Ty the Tasmanian Tiger 3' 2022-10-06 15:45:51 +01:00
Connor McLaughlinandrefractionpcsx2 540cd272e0 FullscreenUI: Display primed achievement list in pause menu 2022-10-06 12:11:56 +01:00
Connor McLaughlinandrefractionpcsx2 0cc665a26b Qt: Add option to hide primed/challenge achievements 2022-10-06 12:11:56 +01:00
Connor McLaughlinandrefractionpcsx2 c0965f7205 Qt: Remove m3u from open file filter 2022-10-06 10:23:48 +01:00
JordanTheToasterandrefractionpcsx2 e092726070 GameDB: Add Ufficiale PlayStation 2 Speciale Platinum 2007
Adds missing demo entry.
2022-10-05 13:00:16 +01:00
JordanTheToasterandrefractionpcsx2 08bf7acb29 GameDB: Add missing Spiderman WoS fix
Adds missing clamp mode fix to PAL version of Spiderman WoS.
2022-10-05 09:18:37 +01:00
refractionpcsx2 2f7d45db09 SPU: Allow up to 200% final volume 2022-10-04 23:42:42 +01:00
rewasdadminandrefractionpcsx2 7c3aa65166 Pad: Native DualShock 3 support in Windows by official Sony driver (sixaxis) 2022-10-04 20:03:48 +01:00
suXinandrefractionpcsx2 5637ff4228 GameDB: WRC Rally Evolved - Fix delay slot slowdowns 2022-10-04 10:01:13 +01:00
PCSX2 Botandlightningterror 7f47ce268f PAD: Update to latest controller database. 2022-10-03 18:05:22 +02:00
Connor McLaughlinandrefractionpcsx2 0af2e4af03 Achievements: Avoid potential crash when parsing malformed responses 2022-10-03 16:10:01 +01:00
Connor McLaughlinandrefractionpcsx2 c379c833e4 Linux: Implement screensaver inhibit for X11 2022-10-03 11:55:31 +01:00
Connor McLaughlinandrefractionpcsx2 f63e1b3760 Qt: Implement screensaver inhibit 2022-10-03 11:55:31 +01:00
JordanTheToasterandrefractionpcsx2 16f7bdcd33 GameDB: Minor game fixes
Undo VU clamp change for Revenge adds missing Burnout 2 entry and Killzone entry and adds half pixel offset normal to Berserk.
2022-10-02 20:21:38 +01:00
Connor McLaughlinandlightningterror bebad5127c Qt: Implement save state backups option 2022-10-02 21:08:58 +02:00
Connor McLaughlinandlightningterror 4907003d3c Qt: Add Delete Save States to load menu 2022-10-02 21:08:58 +02:00
Mrlinkwiiandlightningterror cac62b31b1 linux-various : remove no longer needed shellscript 2022-10-02 21:08:41 +02:00
arcum42 5d3b3319ad Remove references to unused define. 2022-10-02 05:21:51 -07:00
SlyCooperReloadCodedandGitHub 736b5a2a06 GameDB: Fix some game titles and add some missing fixes (#7121) 2022-10-02 13:18:29 +01:00
JordanTheToasterandrefractionpcsx2 92a9aa6d3c GameDB: Update Burnout games VU Clamp mode
Changes the VU Clamp on the Burnout games from none to extra + preserve sign.
2022-10-02 00:42:50 +01:00
lightningterrorandrefractionpcsx2 d908fa5e38 GS/wx: Change TriFilter name and move it to main renderer tab on wx.
Matches Qt behavior.
2022-10-01 17:34:42 +01:00
lightningterrorandrefractionpcsx2 aafb7e22df Qt: Change TriFilter config name. 2022-10-01 17:34:42 +01:00
Connor McLaughlinandrefractionpcsx2 2c1f0d248c GS/HW: Shuffle moves don't need barriers with fbfetch 2022-10-01 17:32:10 +01:00
Connor McLaughlinandrefractionpcsx2 e744fe666b Acheivements: Make login progress indeterminate
It doesn't have a percentage.
2022-10-01 17:29:03 +01:00
Connor McLaughlinandrefractionpcsx2 ea45025bf9 FullscreenUI: Clean boot if resume picked without state 2022-10-01 17:28:50 +01:00
Connor McLaughlinandrefractionpcsx2 ea19514b53 Qt: Fix main window hiding with EFS bug 2022-10-01 17:27:46 +01:00
Connor McLaughlinandrefractionpcsx2 1186025c89 Qt: Add Discord Rich Presence support 2022-10-01 17:27:05 +01:00
Connor McLaughlinandrefractionpcsx2 85b6842557 3rdparty: Add rapidjson and discord-rpc 2022-10-01 17:27:05 +01:00
refractionpcsx2 86685a9db4 CDVD: Increase cycle accuracy + simulate speedup for CLV/CAS swap 2022-10-01 08:18:25 +01:00
Connor McLaughlinandrefractionpcsx2 256a5b94c5 Qt: Hook up reset timestretch button 2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 d1021749bc SPU2: Fix uninitialized bitset
Causes config reloads even when nothing changed.
2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 27229da36f CI: Install libasound2-dev for Linux builds
Hopefully sort out cubeb not building with ALSA support.
2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 44d969c0d2 Qt: Add audio backend selection (only cubeb for now) 2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 9170a5abc1 3rdparty/cubeb: Add cubeb_get_backend_names() 2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 1aa734cb83 3rdparty/cubeb: Silence wasapi output frames logging unless mismatch 2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 3695ae07d5 3rdparty: Move cubeb 93d1fa3fccdc22da37aa59f67b213591797db369 in-tree 2022-10-01 05:00:40 +01:00
Connor McLaughlinandrefractionpcsx2 fea6e1b236 Achievements: Drop OOB poke log messages to verbose 2022-10-01 04:21:50 +01:00
refractionpcsx2 2ff72867e3 Achievements: Fix a couple of typos 2022-10-01 00:26:26 +01:00
Connor McLaughlinandrefractionpcsx2 0419de4baf Qt: Add RetroAchievements implementation 2022-10-01 00:00:02 +01:00
Connor McLaughlinandrefractionpcsx2 843b0b3eb1 3rdparty: Add RAInterface 2022-10-01 00:00:02 +01:00
Connor McLaughlinandrefractionpcsx2 9f2c4c6b59 3rdparty: Add rcheevos 2022-10-01 00:00:02 +01:00
Connor McLaughlinandrefractionpcsx2 9c64193434 HTTPDownloader: Pass content type by reference 2022-10-01 00:00:02 +01:00
Connor McLaughlinandrefractionpcsx2 99fbe4e9ff VMManager: Reload save state ELF in internals
We should serialize this in the state at some point.
2022-10-01 00:00:02 +01:00
Connor McLaughlinandrefractionpcsx2 ffa014f910 ImGuiFullscreen: Add indeterminate background progress 2022-10-01 00:00:02 +01:00
Mrlinkwiiandrefractionpcsx2 1edb856214 Gamedb: fixes for 'Guitar Hero - World Tour' 2022-09-30 23:09:18 +01:00
Connor McLaughlinandrefractionpcsx2 c2cafd1a80 GS/Vulkan: Actually store the readback buffer size
This being missing was causing the buffer to be reallocated every
download.
2022-09-30 14:06:47 +01:00
JordanTheToasterandrefractionpcsx2 da8a79a857 GameDB: Add Trilinear (PS2) to Burnout games
Trilinear makes the image much smoother and more natural.
2022-09-29 14:28:37 +01:00
Connor McLaughlinandrefractionpcsx2 cb73017fbe GameDB: Enable full mipmapping + PS2 trilinear for Ape Escape games 2022-09-29 13:28:38 +01:00
Connor McLaughlinandrefractionpcsx2 56d6014626 GS/HW: Improve PS2 trilinear selection
trilinear_auto should only be set when using basic, trilinear can be
used with PS2 mips.
2022-09-29 13:28:38 +01:00
Connor McLaughlinandrefractionpcsx2 3bbb510b7a GS/HW: Make trilinear filtering behavior consistent across backends
Previously, triln=0 would result in nearest mipmap filtering in
D3D/Vulkan, but forced base level in OpenGL.
2022-09-29 13:28:38 +01:00
Connor McLaughlinandrefractionpcsx2 f2e6c61bfa GS: Use memcmp for GSVector2 comparisons
Single compare-and-branch versus two.
2022-09-29 13:28:38 +01:00
Connor McLaughlinandrefractionpcsx2 f1cb13fd94 GS/TextureCache: Fix non-mipmap sources conflicting with mipmap sources
Fixes building flicker in Burnout 3 with Full mipmapping, as the first
draws don't use mipmapping, but the others do, resulting in the texture
having whatever was last left in it before it was recycled.
2022-09-29 13:28:38 +01:00
RedDevilusandrefractionpcsx2 7d1e7f2b58 GameDB: Jackass
GSHWFix halfpixeloffset for upscaling issue
2022-09-28 17:42:09 +01:00
Ganael LaplancheandGitHub 6229148307 cmake: Fix build on FreeBSD. (#7080)
${pcsx2OSXSources} cannot be built on FreeBSD, so remove them.
2022-09-27 14:40:19 +02:00
lightningterror 18288544a5 GUI-wx: Fix condition is always true/false warnings.
Codacy.
2022-09-27 14:36:36 +02:00
lightningterror de5f310011 USB: Try to fix variable never used warnings.
Codacy.
2022-09-27 14:36:36 +02:00
lightningterror 7ef998e438 GameDB: Add a bunch of Korean games. 2022-09-26 19:45:53 +02:00
Christian Kennyandrefractionpcsx2 0b7c36c456 gitignore: Don't track bad_shader logs 2022-09-26 00:09:03 +01:00
Connor McLaughlinandrefractionpcsx2 bf8d3a044f GS/Vulkan: Fix redundant constant buffer reuploads
Also the redundant descriptor set binds.
2022-09-25 15:12:40 +01:00
Connor McLaughlinandrefractionpcsx2 000de4c72e GS/HW: HLE shuffles (more like copies) done through moves
Fixes broken shadows in the hardware renderer in Final Fantasy XII.
2022-09-25 15:09:46 +01:00
Connor McLaughlinandrefractionpcsx2 5d7ab54340 GS/HW: Vertex/index pointers should be constant 2022-09-25 15:09:46 +01:00
Connor McLaughlinandrefractionpcsx2 d5e8fadc64 VMManager: Fix per-game memory cards getting ejected on boot 2022-09-25 14:32:25 +01:00
JordanTheToasterandlightningterror 5db2bef7b0 GameDB: Disable InstantVU1 for SoTC
Disables InstantVU1 for a moderate increase in FPS due to lower VU % usage.
2022-09-25 14:59:16 +02:00
Connor McLaughlinandlightningterror 41a03c98f3 INISettingsInterface: Use ToChars() for int/float conversion
Avoids locale issues.
2022-09-25 14:49:48 +02:00
Connor McLaughlinandlightningterror af646e4496 Common: Add StringUtil::ToChars() wrapper 2022-09-25 14:49:48 +02:00
Stuart Kennyandlightningterror b3590430c9 MemoryCardFolder: Use icon osd notification method. 2022-09-24 17:21:07 +02:00
Mrlinkwiiandrefractionpcsx2 0aea2bac74 GameDB:add HWfixes to Steel Dragon EX 2022-09-23 19:26:41 +01:00
Stuart Kennyandlightningterror 2915a1a145 MemoryCardFolder: Add write osd notification. 2022-09-23 17:41:11 +02:00
Ty Lamontagneandrefractionpcsx2 14e0aeb4f3 IOPBios: Implement the different iomanx stat file modes 2022-09-20 18:09:58 +01:00
JordanTheToasterandrefractionpcsx2 638f2e09ed GameDB: Correct incorrect GTA SA fix
Fixes a mistake someone made adding ee clamping to GTA SA.
2022-09-20 18:09:46 +01:00
icup321andGitHub 880e2f0d30 GameDB: Spyro NTSC-U bloom fix and add missing PAL demo disc. (#6960)
* Add NTSC-U Spyro fix and missing PAL demo disc

* Add missing PAL Sonic Riders demo disc

* Add HalfPixelOffset fix to Crash Twinsanity demo
Necessary for fixing depth lines in Crash Twinsanity demo.
2022-09-19 18:12:31 +02:00
PCSX2 Botandlightningterror e5698e6c8f PAD: Update to latest controller database. 2022-09-19 18:08:43 +02:00
lightningterror aa075bdf6b GS-wx: Rearrange debug checkboxes in advanced tab graphics settings.
Less confusing and easier to debug.
2022-09-19 01:55:43 +02:00
JordanTheToasterandrefractionpcsx2 96b00e95f5 GameDB: Add missing DB entrys
Adds various missing entry's.
2022-09-18 18:40:11 +01:00
RedPanda4552andGitHub 9394e3ec42 Config: Preserve memcard types instead of wiping to defaults (#7065) 2022-09-18 12:38:34 +01:00
Ty Lamontagneandrefractionpcsx2 435b5a2b27 IOPBios: Differentiate ioman and iomanx dread & getStat HLE
Structure differences with fio_stat_t and fxio_stat_t make them incompatible
2022-09-18 01:52:22 +01:00
Ty Lamontagneandrefractionpcsx2 4ad563f8fc IOPBios: Properly increment host dir iterator
Fixes uLaunchELF and any other homebrew that iterates over directories.
2022-09-18 01:52:22 +01:00
JordanTheToasterandrefractionpcsx2 e94f56a185 Qt: Make FastCDVD per game only
Makes FastCDVD per game only to prevent users enabling a destructive setting globally.
2022-09-17 17:51:54 +01:00
Connor McLaughlinandrefractionpcsx2 a2c140c87f VMManager: Ensure MTGS is finished before resetting 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 1a979a8498 VMManager: Fix inactive per-game bindings taking precedence over global 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 a020e985f2 VMManager: Fix toggling game fixes per-game (stuck enabled) 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 f8d9e6eeb8 InputManager: Split AddBinding() and AddBindings() 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 564c81575f FullscreenUI: Various improvements 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 8b16a7a8c7 Qt: Add cover downloader 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 6b245f34a2 CI: Add libcurl to appimages 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 f17a77c18e Common: Add HTTPDownloader implementation 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 17ac5ffe99 GameList: Use sanitized game titles for covers
Fixes covers for games such as dot hack which use characters incompatble
with the file system.
2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 2b04f0b585 Path: Make sanitize routine follow OS rules 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 22ed71cef4 StringUtil: Add UTF-8 encode and decode 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 1f5d672cbf Qt: Open host input method on imgui text edit
This should open virtual keyboards on devices which do not have a
physical keyboard.
2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 c136bb4ea8 PAD: Add analog stick invert and button deadzone options 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 e28a3ac945 FullscreenUI: Fix controller setting saving 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 3829f574ca 3rdparty/imgui: Round when DPI scaling instead of flooring 2022-09-17 17:51:14 +01:00
Connor McLaughlinandrefractionpcsx2 d8ac919543 3rdparty/imgui: Fix text input with gamepad 2022-09-17 17:51:14 +01:00
Silentandrefractionpcsx2 97e4f39492 QtHost: Fix Unicode command line arguments 2022-09-17 17:51:03 +01:00
Ty Lamontagneandrefractionpcsx2 9d58a1be8b Revert "BiosTools: Allow BIOS region patching"
This reverts commit a4dcaa7c14.
2022-09-17 17:50:46 +01:00
rufotheone-frandrefractionpcsx2 4be34d3cf1 GameDB: fixes letter C + some missing A/B fixes
+ changes asked by refractionpcsx2
2022-09-17 11:05:22 +01:00
Connor McLaughlinandrefractionpcsx2 6ef57bf7d6 Build: Use in-tree imgui
Snapshot was taken at commit 5b9d197b7d
2022-09-16 10:15:28 +01:00
Connor McLaughlinandrefractionpcsx2 c70d833a5e 3rdparty: Move imgui in-tree 2022-09-16 10:15:28 +01:00
Connor McLaughlinandrefractionpcsx2 7b10240297 VMManager: Re-add .mdf as a disc filename
Fixes them not being scannable.
2022-09-16 10:15:17 +01:00
TellowKrinkleandtellowkrinkle 0f0543d3f6 PAD: Remove weird unused binary file 2022-09-16 00:52:28 -05:00
TellowKrinkleandtellowkrinkle 738c8cb630 Core: Remove trailing whitespace from all files 2022-09-16 00:52:28 -05:00
noigeaRandrefractionpcsx2 09c41b6e20 GameDB: More fixes, less missing 2022-09-15 20:51:56 +01:00
Connor McLaughlinandrefractionpcsx2 324eb4d4bf Qt: Fix crash on clearing controller bindings 2022-09-15 16:46:44 +01:00
Connor McLaughlinandrefractionpcsx2 0f24048cd5 GameDatabase: Add gpuPaletteConversion = 2 value
Some games (e.g. Metal Gear Solid 2) use large-ish textures, with a
bunch of different CLUTs/palettes, depending on the draw. Kind-of like a
texture atlas.

This causes issues when texture preloading is enabled, as both VRAM and
GS CPU thread usage increase proporiately to the number of texture:clut
pairs (since it has to be hashed).

An alternative to disabling preloading, which is what we currently do,
is enabling GPU palette conversion in these games. Even though we
ever-so-slightly increase the GPU load due to having to do shader
sampling, the CPU load on the GS thread is considerably reduced, and
overall performance is greater. In theory it'll also achieve higher
cache hit rates on the GPU, since we're not duplicating a bunch of
textures.

However, as a general rule of thumb, we don't want to encourage people
to enable paltex, as most games run slower with it on. So, what this PR
does, is add a GameDB option for these types of games, to enable paltex
when texture preloading is set to full/hash cache, but otherwise leave
the setting alone. The best of both worlds.

NOTE: I've also forced paltex=0 for Spider-Man 2, as it uses a massive
number of palettes which can cause descriptor issues in DX12/Vulkan. A
perfect example of where you *don't* want to use paltex.
2022-09-15 12:24:43 +01:00
noigeaRandrefractionpcsx2 0ffdc485d7 GameDB: Fix DOA 2 naming. Yamasa Digi World add missing & fix naming 2022-09-15 12:23:50 +01:00
Connor McLaughlinandrefractionpcsx2 6810a9d593 Qt: Deduplicate interface code and reduce core coupling
This enables more code sharing between interfaces in the future (e.g.
nogui, gsrunner, etc). Eventually I'll move everything in Frontend/ to
its own project.

 - VMManager now no longer depends on anything in Frontend.
 - Moved INISettingsInterface out of Frontend.
 - Log settings can now be overridden per-game (if you really want to)..
 - Hotkeys get their own file.
2022-09-15 11:50:51 +01:00
Connor McLaughlinandrefractionpcsx2 c96f1d28e6 Qt: Fix fullscreen/window size being enabled in game list 2022-09-15 11:50:40 +01:00
neonoxdandlightningterror f2d86f2782 Qt: Scroll GameList by pixels using scrollwheel 2022-09-14 00:38:49 +02:00
noigeaRandrefractionpcsx2 ee88ea90ee GameDB: Fix Kaidou Battle upscaling and add missing games 2022-09-13 21:50:12 +01:00
lightningterror 7c1bf15618 tools: Cleanup trailing whitespace.
Codacy warning.
2022-09-13 20:19:53 +02:00
lightningterror fdb170b443 Core: Remove unused IopSif.cpp file.
Codacy warnings.
2022-09-13 20:19:53 +02:00
lightningterror 1fa7ae4f0d PAD: Cleanup unused variable warnings.
Codacy.
2022-09-13 20:19:53 +02:00
PCSX2 Botandlightningterror 7641890910 PAD: Update to latest controller database. 2022-09-12 18:16:09 +02:00
JordanTheToasterandrefractionpcsx2 72c78fc163 UI: Fullscreen UI typo fix
Fixes a typo in cycle skip.
2022-09-12 10:23:27 +01:00
SupervisedThinkingandlightningterror 8d8c076931 CMake: fix Xrandr
- fix path to includes
- fix lib name
2022-09-11 16:30:21 +02:00
JordanTheToasterandrefractionpcsx2 f3f495d23b WX: Add Disable Hardware Readbacks option
Adds the missing disable hardware readback option to WX.
2022-09-11 01:10:31 +01:00
Connor McLaughlinandrefractionpcsx2 bc3729c930 iR5900: Skip reloading COP2 flags register when it's not used 2022-09-10 15:26:30 +01:00
Connor McLaughlinandrefractionpcsx2 5a0c8c9f32 iR5900Analysis: Always set COP2 status flag bit for VSQRT/VRSQRT/VDIV
These update flags unconditional on FMAC.
2022-09-10 15:26:30 +01:00
JordanTheToasterandrefractionpcsx2 367a69cdfe GameDB: MGS2 Document of text fixes for more versions
Adds EETimingHack to more versions of MGS2 the document of to fix the flickering broken text.
2022-09-10 14:47:34 +01:00
Connor McLaughlinandrefractionpcsx2 e8230ee01f Qt: Fix load input profile/reset controller defaults
Same deal as #7029.
2022-09-10 05:19:09 +01:00
Connor McLaughlinandrefractionpcsx2 99f1ad0ea6 Qt: Fix crash when autobinding controller
Regression from #7016.
2022-09-10 04:40:56 +01:00
JordanTheToasterandrefractionpcsx2 11d3326d73 GameDB: Beyond Good and Evil rendering fix
Fixes shield rendering on BGAE.
2022-09-10 02:59:27 +01:00
KrossXandrefractionpcsx2 7dd88213b1 Qt: include more entry strings in search 2022-09-09 21:25:49 +01:00
Connor McLaughlinandrefractionpcsx2 e0cb165927 LRUCache: Fix Evict() removing too many items 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 1e660c8e85 Qt: Fix possible crash when starting game while scanning 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 e8704adc67 GzippedFileReader: Don't double open when creating index 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 43d6ddd7cf VMManager: Add warning for unsafe settings on boot 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 6e0ac7fa75 HostDisplay: Make GL/D3D timestamp queries slightly less rubbish 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 800aca6f0f GS/OpenGL: Force UBO reupload on restore api state 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 a228582984 Host: Add GetResourceFileTimestamp() 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 9f9f8e0e39 GameList: Fix title for ELFs 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 3d6f4629e9 PAD: Fix copying input sources 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 6fca0dac0e VMManager: Only trigger hotkeys with valid VM 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 22e9aea827 Config: Fix frame rate being parsed ever-so-slightly off
Also converts from double to float, we don't need additional precision
for storing these values.
2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 e064e96c96 HostDisplay: Make global pointer instead of function 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 b667236c92 Qt: Combine EmuThread.cpp and QtHost.cpp
These mostly called back between one another.
2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 e4df563811 Qt: Implement settings reset 2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 d86abebb50 VMManager: Add SetDefaultSettings()
Also removes the affinity control default for <=2 threads, best to let
the OS handle this.
2022-09-09 21:21:14 +01:00
Connor McLaughlinandrefractionpcsx2 1b3bf89ee8 PAD: Split set default controller and hotkey settings 2022-09-09 21:21:14 +01:00
noigeaRandrefractionpcsx2 291063bd98 GameDB: Add missing games 2022-09-09 20:04:10 +01:00
TellowKrinkleandtellowkrinkle 4c298ca484 GS: Add zequal to GSScanlineSelector to_string 2022-09-08 19:55:09 -05:00
TellowKrinkleandtellowkrinkle 650dc8bc6a GS: Fix zequal handling in CDrawScanline
I somehow didn't use the same algorithm as the asm version originally
2022-09-08 19:55:09 -05:00
Mrlinkwiiandrefractionpcsx2 2ee8236365 Gamedb: upscaling fixes for 'Urbz, The - Sims in the City' 2022-09-08 22:30:00 +01:00
JordanTheToasterandrefractionpcsx2 4707c02a34 GameDB: Deus Ex various fixes
Adds round sprite half preload frame data and partial texture preloading to Deus Ex.
2022-09-08 21:38:01 +01:00
JordanTheToasterandrefractionpcsx2 d0faa14760 GameDB: Death by Degrees FMV line fixes
Adds align sprite to Death by Degrees to fix FMV lines.
2022-09-08 18:28:01 +01:00
Connor McLaughlinandlightningterror 19725deb7e FullscreenUI: Remove accurate DATE option
It doesn't exist anymore.
2022-09-08 12:45:48 +02:00
TellowKrinkleandtellowkrinkle 81cafd21d0 GS:MTL: Don't override GSTexture::Save with a TODO
There's a working default implementation
2022-09-08 02:20:26 -05:00
TellowKrinkleandtellowkrinkle 365c1c3f3e GS:MTL: Implement GPU usage tracking 2022-09-08 02:20:26 -05:00
TellowKrinkleandtellowkrinkle fbc3120c47 GS:MTL: Ensure prim id init actually writes 2022-09-08 02:20:26 -05:00
TellowKrinkleandtellowkrinkle 66093c3278 GS:MTL: Add barrier counting 2022-09-08 02:20:26 -05:00
Ty Lamontagneandrefractionpcsx2 7d4ca441d5 clang-format: pcsx2/IopBios.cpp 2022-09-07 20:54:12 +01:00
Ty Lamontagneandrefractionpcsx2 cee8598b3f IOPBios: Hook iomanx library as well as ioman
Fixes fileXio incompatibility
2022-09-07 20:54:12 +01:00
Mrlinkwiiandrefractionpcsx2 256e845e7a Gamedb: Fix 'Muppets Party Cruise' 2022-09-07 20:46:48 +01:00
lightningterrorandrefractionpcsx2 f39ac6f58b Qt: Remove Accurate DATE from Qt gui. 2022-09-07 12:17:08 +01:00
lightningterrorandrefractionpcsx2 a397de448b GS-wx: Remove Accurate DATE from wx gui. 2022-09-07 12:17:08 +01:00
lightningterrorandrefractionpcsx2 62adad0739 GS-config: Remove Accurate Date from the config. 2022-09-07 12:17:08 +01:00
lightningterrorandrefractionpcsx2 3d647fe55a GS-hw: Remove Accurate DATE option, no longer needed. 2022-09-07 12:17:08 +01:00
JordanTheToasterandrefractionpcsx2 65b0511d9e GameDB: Kikou graphics fixes
Disables mVU flag speedhack to fix broken graphics.
2022-09-07 09:18:30 +01:00
Connor McLaughlinandrefractionpcsx2 16a33e42e2 GS/Vulkan: Discard instead of clear for PrimID setup fill 2022-09-07 09:18:11 +01:00
Connor McLaughlinandrefractionpcsx2 81c0e000e7 GS/DX12: Discard instead of clear for PrimID setup fill
We're writing the render area anyway.
2022-09-07 09:18:11 +01:00
Connor McLaughlinandrefractionpcsx2 d4a5a714fb GS/DX12: Fix incorrect topology on PrimID DATE setup 2022-09-07 09:18:11 +01:00
rufotheone-frandGitHub e60e0c02c0 GameDB: fixes letter B (#6973) 2022-09-07 09:17:28 +01:00
TellowKrinkleandtellowkrinkle 5fa35c5273 CMake:MacOS: Don't strip qt binaries 2022-09-07 01:18:34 -05:00
TellowKrinkleandlightningterror 95ad6b8ab4 GS:DX11: Add primid destination alpha support 2022-09-06 21:07:56 +02:00
TellowKrinkleandlightningterror 1b34eb14f8 GS: Pass through primitive ID in geometry shaders in DX12 and VK
Fixes primid destination alpha on sprites
2022-09-06 21:07:56 +02:00
TellowKrinkleandlightningterror 412480b326 GS: Don't add 10 to date flag to indicate initialization
We already have 1 and 2 dedicated to the job
2022-09-06 21:07:56 +02:00
TellowKrinkleandlightningterror 0500824e57 GS:Vk: Change primitive_id enable to match the new meaning
A bit messy, due to the fact that its support piggybacks on support of other features, instead of having a dedicated feature flag
2022-09-06 21:07:56 +02:00
TellowKrinkleandlightningterror 3e0f3d05e2 GS: Rename image_load_store capability to primitive_id
The algorithm it enables has changed for all renderers, and no longer needs image_load_store
2022-09-06 21:07:56 +02:00
TellowKrinkleandlightningterror 62f9b16139 GS:OGL: Use blend min for primid destination alpha 2022-09-06 21:07:56 +02:00
TellowKrinkleandlightningterror 80523828c7 GS:HW: Properly use primid dst alpha as a fallback to barrier dst alpha
Even when we would have otherwise used barrier over primid if both were supported
2022-09-06 21:07:56 +02:00
PCSX2 Botandlightningterror 979a105071 PAD: Update to latest controller database. 2022-09-05 18:22:28 +02:00
TellowKrinkleandtellowkrinkle ea81b74e3b GS:OGL: Add fetch_rt function to shader 2022-09-04 23:02:44 -05:00
TellowKrinkleandtellowkrinkle 1864440f5c GS:OGL: Support disabling texture barrier 2022-09-04 14:47:39 -05:00
JordanTheToasterandrefractionpcsx2 b96594b17c GameDB: Corvette game fixes
Adds half pixel offset special aggressive and disables MTVU for Corvette.
2022-09-02 19:38:09 +01:00
Connor McLaughlinandrefractionpcsx2 97960a2232 microVU: Fix program dumping 2022-09-02 11:21:30 +01:00
refractionpcsx2 5fc73f87f4 OSD: Correct region2 parameter offset. 2022-09-01 23:19:16 +01:00
JordanTheToasterandrefractionpcsx2 8ca5cb18a3 GameDB: General title fixes and adds a gamefix
Corrects some more titles and adds preload frame data to "Takahashi Naoko no Marathon Shiyou yo!".
2022-09-01 16:31:53 +01:00
TellowKrinkleandlightningterror 517f3b7709 GS:HW: Don't skip FBW 0 2022-09-01 11:01:50 +02:00
TellowKrinkleandlightningterror 603f863b71 GS: Don't clamp fbw to 1
fbw zero is a thing
2022-09-01 11:01:50 +02:00
TellowKrinkleandlightningterror e40a93e389 GS: Don't clamp scissor to fbw
HW tests indicate this doesn't happen
2022-09-01 11:01:50 +02:00
lightningterror 6279ae63ce GS-hw: Remove remaining 24bit destination checks for Ad. 2022-09-01 10:28:42 +02:00
Connor McLaughlinandrefractionpcsx2 cb2a21ef19 IopBios: Fix opening host: or host:. as a directory 2022-08-31 21:29:01 +01:00
lightningterror edc82d77a5 GS-hw: Improve how we handle blending on 24bit with Ad factor in renderer. 2022-08-31 20:34:51 +02:00
TellowKrinkleandlightningterror e89612e5b9 GS: Use accumulation blend when alpha is known to be 1 2022-08-31 18:17:43 +02:00
rufotheone-frandrefractionpcsx2 9150e69783 GameDB: some title fixes letter A + SCAJ-30004 + SLPM-62346
+ fix "Attheraces Presents Gallop Racer" double space
2022-08-31 15:33:47 +01:00
JordanTheToasterandrefractionpcsx2 4b95112724 GameDB: Various title fixes and game fixes
Fixes various titles and adds autoflush to Yumeria.
2022-08-31 11:17:03 +01:00
PCSX2 Botandlightningterror b45748fead PAD: Update to latest controller database. 2022-08-30 18:23:29 +02:00
Mrlinkwiiandrefractionpcsx2 0b3052ced2 Gamedb: fix incorrect korean serials 2022-08-30 14:36:16 +01:00
JordanTheToasterandrefractionpcsx2 aae53fb9da GameDB: Fix "Curious George" region
Changes the region from NTSC-Unk to the correct NTSC-HK.
2022-08-30 09:46:35 +01:00
Mrlinkwiiandrefractionpcsx2 291d32bd35 GameDB: add missing serial for 'Hyper Sports 2002 Winter' 2022-08-30 01:18:51 +01:00
Connor McLaughlinandrefractionpcsx2 6386be09c2 CMake: Throw error when building Qt with PACKAGE_MODE
We don't support this.

1. It doesn't make sense to put data in /usr/share since it's not shared between applications.
2. Makes the application not self-contained for easily being moved/removed.
3. Means you can't have multiple versions installed.
4. Every other platform is self-contained (Windows, Mac).
2022-08-29 13:58:22 +01:00
Connor McLaughlinandrefractionpcsx2 05bed05afe Frontend: Add fullscreen UI implementation 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 5b9d197b7d 3rdparty/imgui: Include imgui_stdlib 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 9cce6945e6 Common: Add Image and Easing classes 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 33f1e51ebc 3rdparty: Move jpgd from pcsx2 to separate static lib 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 d466184a02 MTGS: Support 'running idle', i.e. redisplaying the current frame 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 be3f120548 VMManager: Support per-game controller settings
Global bindings will be ignored in such a case.
2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 2e303da384 Qt: Move pressure modifiers to settings tab 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 dfc3fd8e58 VMManager: Add icons to some OSD messages 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 51e3ec27d8 VMManager: Clear last elf/serial on shutdown 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 1ec76ce248 VMManager: Move semantics for VMBootParameters 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 9012afc534 Qt: Forward text input to ImGui 2022-08-29 13:39:09 +01:00
Connor McLaughlinandrefractionpcsx2 a19045f9d6 Host: Add ConfirmMessage() and OpenURL() 2022-08-29 13:39:09 +01:00
Mrlinkwiiandrefractionpcsx2 d18c8976b9 readme: update readme 2022-08-29 13:31:56 +01:00
Mrlinkwiiandrefractionpcsx2 5485ef4f50 CI: update to 20.04 for WX 2022-08-29 13:31:56 +01:00
TellowKrinkleandtellowkrinkle f4a56ae106 GHActions:macOS: Use ccache 2022-08-28 18:35:03 -05:00
TellowKrinkleandtellowkrinkle 280316dceb Qt: no-pch support 2022-08-28 18:35:03 -05:00
Connor McLaughlinandrefractionpcsx2 9094ee0dc6 D3D11HostDisplay: Migrate to wil 2022-08-27 13:52:12 +01:00
Connor McLaughlinandrefractionpcsx2 cad489480c Frontend: Remove unused code 2022-08-27 13:52:12 +01:00
Connor McLaughlinandrefractionpcsx2 9655d28a23 Common: Remove unused code 2022-08-27 13:52:12 +01:00
refractionpcsx2 76d3299690 GS-Dumps: Fix Local->Host download size 2022-08-27 02:43:03 +01:00
lightningterror 7b846b42e3 GameDB: Remove R&C 3 patch for ps2 demo disc.
Broke Jak 3 causing it to hard crash.
2022-08-27 01:43:58 +02:00
refractionpcsx2 b8ca60ebd5 DEV9: Codacy fix codacy errors and warnings 2022-08-27 00:33:59 +01:00
refractionpcsx2 ddb9f0b95d SPU2: Codacy fix codacy errors and warnings 2022-08-27 00:33:59 +01:00
refractionpcsx2 93f4277b3c UI-Files: Codacy fix codacy errors and warnings 2022-08-27 00:33:59 +01:00
refractionpcsx2 f841a8ba58 Core: Fix codacy errors and warnings 2022-08-27 00:33:59 +01:00
refractionpcsx2 4d4825de75 GS: Fix codacy warnings 2022-08-27 00:33:59 +01:00
Mrlinkwiiandlightningterror a71bac037c Misc: fix some codacy warnings 2022-08-26 22:58:08 +02:00
lightningterror 02e4e4da01 USB: Cleanup const reference warnings.
Codacy warning: Function parameter should be passed by const reference.
2022-08-26 20:57:57 +02:00
lightningterror 0bf6f9d596 CDVD: Cleanup const reference warning.
Codacy warning: Function parameter should be passed by const reference.
2022-08-26 20:57:57 +02:00
RedDevilusandrefractionpcsx2 472c6efc12 GameDB: Re-ordering gshwfix
GameDB: Star Wars Episode 3 re-ordering
2022-08-26 19:32:28 +01:00
lightningterror 66d88ed10b GS: Fix Wunused-but-set-variable, Wunused-variable warnings. 2022-08-26 14:42:37 +02:00
lightningterror 4439b3ad22 PAD: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list.
2022-08-26 14:33:20 +02:00
lightningterror 7c6a838d7f GUI-Wx: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list.
2022-08-26 14:33:20 +02:00
refractionpcsx2 5c951afa64 GameDB: Remove SoftwareFMV switches no longer needed 2022-08-26 09:07:42 +01:00
refractionpcsx2 878e06cd36 GS-HW: Limit BP overlap check to stop FMV flicker.
Games changing the double buffer addresses get screwed up, make sure we don't misdetect
2022-08-26 09:07:42 +01:00
refractionpcsx2 4ef879d1f2 GS-HW: Scale display texture width in TC. 2022-08-26 09:07:42 +01:00
refractionpcsx2 b74f91b868 GS-HW: Expand width on output read if DBX offset 2022-08-26 09:07:42 +01:00
TellowKrinkleandtellowkrinkle 693790a19f GS:MTL: Expand lines and sprites in vertex shader 2022-08-26 01:18:00 -05:00
lightningterror 98724979cb GUI-Wx: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list.
2022-08-26 02:16:00 +02:00
lightningterror ab430355ec CDVD: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list
2022-08-26 02:16:00 +02:00
lightningterror 060a8f6345 PAD: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list
2022-08-26 02:16:00 +02:00
lightningterror 97aaf3ef9b MemoryCard: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list.
2022-08-26 02:16:00 +02:00
lightningterror 6eb7f5f962 DebutTools: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list.
2022-08-26 02:16:00 +02:00
lightningterror 313fe1ca2c GS: Fix variable initializations.
Codacy Warning: Variable 'variable' is assigned in constructor body. Consider performing initialization in initialization list.
2022-08-26 02:16:00 +02:00
TellowKrinkleandlightningterror ce34fbe502 3rdparty: Update cubeb 2022-08-25 15:16:46 +02:00
TellowKrinkleandlightningterror 562e9bfebb GS:FindMinMax: sprites use flat Z and color 2022-08-25 15:15:07 +02:00
TellowKrinkleandlightningterror c2fbe5c606 GS: Fix up FindMinMax handling of swapped lines and final triangles 2022-08-25 15:15:07 +02:00
TellowKrinkleandlightningterror f53cb0fae7 GS: Reduce FindMinMax instantiation count 2022-08-25 15:15:07 +02:00
JordanTheToasterandrefractionpcsx2 9d8b93a269 Revert "GS-hw: Purge MidnightClub3 crc hacks."
This reverts commit f53fbd6282.
2022-08-25 10:39:02 +01:00
raid273andrefractionpcsx2 e65ef95027 GameDB: Added memcardFilters to Armored Core - Last Raven 2022-08-24 09:11:48 +01:00
refractionpcsx2 3455c2955f CDVD: Fix integer division on floats and fix logging 2022-08-24 08:43:11 +01:00
JordanTheToasterandrefractionpcsx2 4abd395efa GameDB: Major League Baseball 2K5 Hang fix
Adds EE Clamp Extra + Sign to MLB 2K5 and the world series edition.
2022-08-24 08:41:56 +01:00
lightningterror c332bd198a GS-wx: Remove unused FMVSoftwareRendererSwitch config. 2022-08-24 01:42:28 +02:00
lightningterror 6c395cc07d GS-wx: Set texture preloading to full as default.
Already is on Qt.
2022-08-24 01:37:29 +02:00
lightningterror 7eea2fba9b GS-wx: Update tooltips. 2022-08-24 01:36:37 +02:00
JordanTheToasterandrefractionpcsx2 e89115a027 GameDB: Fixing fixes
Fixes some previous fixes so those fixes actually work or don't break the game
2022-08-23 12:18:32 +01:00
refractionpcsx2 00ffa42f50 UI-Qt: Hide Dolby Pro Logic Decoding (It doesn't do anything) 2022-08-23 10:35:55 +01:00
TellowKrinkleandtellowkrinkle e55825fd88 GHActions:Windows:CMake: Properly exit on failed build 2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle a50a9fcf9a GHActions: CMake builds are SSE4 2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle ce8679a978 CMake: Use full LTO
Speeds up Vulkan backend a bit compared to LTO_PCSX2_CORE, since Vulkan calls into a lot of common methods
2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle 5d6348fbf9 CMake: Add GS- flag to MSVC bulds 2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle 63e9d47f09 CMake: Add SPU and GS to LTO_PCSX2_CORE LTO 2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle 8cc7343201 GHActions: Publish PDB for cmake builds 2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle 2aabd54e6a GHActions: Disable buildcache on windows
Not compatible with PDB
2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle bb56f274c8 CMake: Enable PDB generation in Release builds 2022-08-23 03:32:26 -05:00
TellowKrinkleandtellowkrinkle 241d7335e4 SDL2: Remove mac crash workaround for SDL 2.0.22
2.24 is here!
2022-08-23 03:24:57 -05:00
TellowKrinkleandtellowkrinkle bc7037bb52 3rdparty: Upgrade SDL to 2.24 2022-08-23 03:24:57 -05:00
TellowKrinkleandtellowkrinkle e7e5814214 3rdparty: Sort SDL vcxproj entries 2022-08-23 03:24:57 -05:00
lightningterror 4c9fbd3fba GS-hw: Cleanup GSRendererHW.cpp.
Constants,duplicate declarations, initializations, null pointers.
2022-08-23 02:38:49 +02:00
PCSX2 Botandlightningterror 566d397bd1 PAD: Update to latest controller database. 2022-08-22 19:40:29 +02:00
JordanTheToasterandrefractionpcsx2 2da65cdd5f GameDB: Add some missing demos
Adds missing demos
2022-08-22 08:49:41 +01:00
JordanTheToasterandrefractionpcsx2 e3eae7fbe8 GameDB: Various game fixes and missing entrys
Adds software FMV switch to The Thing JP and texture preloading to partial for Osouji Sentai Clean Keeper H
2022-08-20 23:57:48 +01:00
TellowKrinkleandrefractionpcsx2 91601e5647 GS: Manually do bilinear sampling when converting RGBA to depth
Shader bilinear doesn't properly handle the case where r overflows into g (or g overflows into b, etc)
2022-08-20 10:12:24 +01:00
TellowKrinkleandrefractionpcsx2 882c09b870 Vulkan: Format convert.glsl 2022-08-20 10:12:24 +01:00
JordanTheToasterandrefractionpcsx2 1d7a130bd1 GameDB: Tomb Raider Angle of Darkness effect fixes
Adds autoflush to restore the lava fire effect
2022-08-20 09:53:16 +01:00
iMineLinkandrefractionpcsx2 202fb5fef3 GS: improve haunting ground hw tc hack.
when clearing the render target, also discard all the dirty
rectangles previously marked, to avoid spurious uploads
later.
2022-08-19 10:55:27 +01:00
JordanTheToasterandrefractionpcsx2 f73d7b4cb9 GameDB: Driving Emotion Type-S fixes
Adds VUSyncHack and VU Clamp mode Extra + Sign.
2022-08-19 10:45:04 +01:00
TellowKrinkleandtellowkrinkle 48d3d38e84 GS: Fix wx replayer readbacks
WX runs GS commands directly, so GS isn't open
2022-08-18 20:35:35 -05:00
lightningterror 11c903a3e9 GS: Cleanup GSState.cpp.
constants, scope, duplicate declarations, initializations.
2022-08-18 23:04:13 +02:00
iMineLinkandrefractionpcsx2 4992659b46 GS: fix out of bounds access to index buffer. 2022-08-18 20:36:46 +01:00
JordanTheToasterandrefractionpcsx2 7285eca249 GameDB: Shellshock Nam 67 Upscaling fixes
Adds round sprite half to Shellshock Nam 67
2022-08-17 19:46:13 +01:00
lightningterror dc8021e952 GS: Fix Wsign-compare warning. 2022-08-17 19:47:48 +02:00
Connor McLaughlinandlightningterror fb18143791 Qt: Fix newline printed for guest printf on Linux 2022-08-17 19:38:02 +02:00
JordanTheToasterandrefractionpcsx2 475551b0d9 GameDB: Interlace and upscale fixes for Cocoto Fishing Master
Adds interlacing Blend BFF and half pixel offset vertex to Cocoto Fishing Master
2022-08-17 00:26:56 +01:00
refractionpcsx2 5447da0588 GS: Don't do blend_mix on HDR 2022-08-16 20:54:55 +01:00
refractionpcsx2 1b18e02fe0 GS: Add constant adjustment in blend mix when reverse subtracting. 2022-08-16 20:54:55 +01:00
KrossXandrefractionpcsx2 2e63a4c037 Qt: Add ProLogic decoding audio settings 2022-08-16 20:28:10 +01:00
JordanTheToasterandrefractionpcsx2 2d0e0c8fcc Qt: Change name of Adjust to Host Refresh Rate
Changes the name of Adjust To Host Refresh Rate to Scale to Host Refresh Rate.
2022-08-16 19:58:51 +01:00
Daisoujiandrefractionpcsx2 2b61e10d91 QT: Changing checked to Checked 2022-08-16 19:58:37 +01:00
JordanTheToasterandrefractionpcsx2 97ce72ed07 Qt: Add missing description box texts
Adds missing texts descriptions to VSync Internal Resolution Screenshots and Integer Scaling.
2022-08-16 08:44:37 +01:00
refractionpcsx2 fcbf9f7d8f GameDB: Upscaling fix for Naruto Ultimate Ninja 5/Narutimate Accel 2 2022-08-15 20:41:06 +01:00
refractionpcsx2 c2a68aa0b8 GS: Fix bug where incorrect verticles were saved on flush
Probably didn't matter in most cases, but for autoflush draws, it certainly does.
2022-08-15 18:27:09 +01:00
refractionpcsx2 080c70e8a8 GS: Add shortcut for Autoflush on Tri-Strip/Fan 2022-08-15 18:27:09 +01:00
refractionpcsx2 c11030dde5 GS: Improve autoflush detection.
Old way didn't really work with triangles, especially triangle fans.  Some games will be slower, others faster.
2022-08-15 18:27:09 +01:00
JordanTheToasterandrefractionpcsx2 a2e6a8e41f GameDB: DBZ Budokai Tenkaichi fixes
Adds half pixel offset special and full round sprite to Dragon Ball Z Budokai Tenkaichi
2022-08-15 15:29:34 +01:00
Mrlinkwiiandrefractionpcsx2 ec5f614a25 Gamedb: add upscaling fixes to 'Charlie's Angels' 2022-08-15 09:40:03 +01:00
lightningterror 23338319a0 PAD: Fix Wsign-compare warning. 2022-08-14 20:48:04 +02:00
lightningterror 191c7fdf30 GS: Fix Wunused-private-field warning. 2022-08-14 20:48:04 +02:00
refractionpcsx2 1342ed2afe GS: Revert #6838 2022-08-14 16:57:59 +01:00
Left-EmptyandGitHub 69b0193535 gameDB: Kessen 2 NTSC-J refraction patch fix (#6842) 2022-08-14 12:22:04 +01:00
Connor McLaughlinandrefractionpcsx2 db2489a555 GS/TextureCache: Fix texture resize in DX11 2022-08-14 03:54:19 +01:00
Silentandrefractionpcsx2 b191126f36 Workflows: Download cheats from pcsx2_patches repo on build time 2022-08-14 02:58:10 +01:00
JordanTheToasterandrefractionpcsx2 ef0de38624 GameDB: Add various Burnout fixes
Adds various Burnout fixes and adds a missing demo entry for Burnout Revenge
2022-08-14 01:56:46 +01:00
noigeaRandrefractionpcsx2 3d0a43d0e7 GameDB: Fix typos in game names 2022-08-13 21:27:52 +01:00
Dreadmothandrefractionpcsx2 874be7ea8b GameDB: Remove half-pixel offset from Mercenaries
Remove half-pixel offset from Mercenaries - it breaks the skybox.
2022-08-13 21:26:45 +01:00
Mrlinkwiiandrefractionpcsx2 a93034ad59 Gamedb: add fixes for 'World Rally Championship' NTSC-J versions 2022-08-13 17:02:18 +01:00
JordanTheToasterandrefractionpcsx2 134cee6adc WX: Change default sound module
Changes the default sound module from XAudio2 to Cubeb to prevent USB crashing and parity with Qt
2022-08-13 16:48:58 +01:00
TellowKrinkleandlightningterror cb64e8d504 GS:HW: More accurate blend equation for blend mix 2022-08-13 00:01:23 +02:00
JordanTheToasterandrefractionpcsx2 35a6dfb52a Config: Change default dump compression
Changes default dump compression from uncompressed to LZMA (xy)
2022-08-12 19:30:08 +01:00
Mrlinkwiiandrefractionpcsx2 1c276db76f Gamedb: add missing 'Ace Combat 04' entry 2022-08-12 18:13:04 +01:00
Mrlinkwiiandrefractionpcsx2 400e0f1dd4 Gamedb: add missing Alpine Racer 3 entries 2022-08-11 14:05:57 +01:00
Connor McLaughlinandrefractionpcsx2 9a7ed81759 Qt: Improve controller settings and add macro UI 2022-08-10 17:25:11 +01:00
Connor McLaughlinandrefractionpcsx2 6f40cf9beb Qt: Only hide global texture offset/skipdraw in release builds 2022-08-10 17:25:11 +01:00
Connor McLaughlinandrefractionpcsx2 307028734f Qt: Fix several issues in SettingWidgetBinder
- Possible nullopt value().
 - Incorrect loading of some folder values.
 - Enable per-game setting of spinboxes.
2022-08-10 17:25:11 +01:00
refractionpcsx2 cd2d7c91c3 GS: Add slow path for odd width 4bpp host->local transfers 2022-08-10 16:52:07 +01:00
TellowKrinkleandtellowkrinkle 8b375d66fa GHActions:MacOS: Don't fail on failed brew unlink
If brew can't unlink them, they're not there and there's no need to do anything
2022-08-10 04:28:31 -05:00
JordanTheToasterandrefractionpcsx2 8f367abe0b GameDB: Ace Combat 5 Fixes
Adds texture preloading partial to Ace Combat 5 for better performance.
2022-08-10 06:44:20 +01:00
Mrlinkwiiandrefractionpcsx2 fdc84be0d9 Gamedb: upscaling fixes for Shadow of Rome 2022-08-10 06:44:00 +01:00
BreakPointsandrefractionpcsx2 edfceaad14 Qt: Force helpText size to avoid overflow at default size
Increase minimum size of helpText to match max
2022-08-09 15:35:52 +01:00
JordanTheToasterandrefractionpcsx2 40fda5067d GameDB: Add DBZ Budokai Tenkaichi 2 fixes
Adds half pixel offset normal to DBZ BT 2 and removes full round sprite to fix the insane amount of ghosting in some areas
2022-08-09 15:33:42 +01:00
lightningterror 573706e5e4 GS-hw: Don't disable second output on blend mix when using constant factor.
We don't want to disable second output when using blend mix1 above 1.0f Af.
Reason is we change Af to As and later output it on second output for hw blending.
2022-08-08 18:11:28 +02:00
PCSX2 Botandlightningterror 1ef4acc2af PAD: Update to latest controller database. 2022-08-08 18:11:16 +02:00
lightningterror 6035db3231 GS-d3d11: Disable blending when color isn't written.
Fixes d3d11 crashing on mgs3 using intel igpu.
2022-08-08 12:51:17 +02:00
Mrlinkwiiandrefractionpcsx2 2cd44412f6 Gamedb: upscaling fixes for Poison Pink/ Eternal Poison 2022-08-08 11:21:14 +01:00
JordanTheToasterandrefractionpcsx2 c149fe31fb GameDB: Add missing Korean serials
Adds missing Korean serials as well as the accompanying fixes
2022-08-08 04:40:02 +01:00
JordanTheToasterandrefractionpcsx2 0e24d638c9 GameDB: Fixes for Devil Kings
Adds Special HPO to Devil Kings
2022-08-07 20:37:31 +01:00
JordanTheToasterandrefractionpcsx2 5c056f0c4d GameDB: Add Disaster Report fixes
Adds auto flush to Disaster Report to correct an inaccurate blur filter
2022-08-07 18:57:35 +01:00
lightningterror 62b838427f GS-hw: Purge tri ace crc hacks.
Star Ocean 3, Valkyrie Profile 2, Radiata Stories.

The crc hacks aren't that needed anymore since right now D3D is much faster than it used to be.
2022-08-07 14:13:56 +02:00
BreakPointsandrefractionpcsx2 ad529c10ab Qt Updater: Copy new icon to updater
So that the updater benefits from the new icon changes in #6785 (file size, sharpness of small icon sizes)
2022-08-07 13:09:26 +01:00
noigeaRandGitHub 8ef7399612 GameDB: Add missing Japanese games (#6790) 2022-08-07 13:08:59 +01:00
JordanTheToasterandrefractionpcsx2 939c1f0f29 GameDB: Add 007 NightFire fixes
Adds half pixel offset special to 007 NightFire
2022-08-07 13:08:22 +01:00
lightningterror 6b48cf574d GS-hw: Adjust how we handle specific blend mix cases.
Replace Cs*As + Cd*(1 - As) with Cs*As - Cd*(As - 1).
Replace Cs*F + Cd*(1 - F) with Cs*F - Cd*(F - 1).
As - 1 or F - 1 subtraction is only done for the dual source output (hw blending part)
since we are changing the equation.
Af will be replaced with As in shader and send it to dual source output.

Also check if A*Alpha in the shader overflows, if it does then adjust the
alpha that is sent for HW blending further to compensate.
2022-08-07 14:08:04 +02:00
Mrlinkwiiandlightningterror 1478819258 GS-hw: Purge SkyGunner crc hacks. 2022-08-07 03:07:04 +02:00
Mrlinkwiiandlightningterror f53fbd6282 GS-hw: Purge MidnightClub3 crc hacks. 2022-08-07 03:06:51 +02:00
lightningterror 60e6e1f242 Qt: Fix Wunused-but-set-variable warnings. 2022-08-07 03:00:22 +02:00
lightningterror 7a5f63e0f5 GS-metal: Move PABE shader bit to the top of sw blending.
Early return when there is no sw blending, no need to run the blend code.
Optimization.
2022-08-06 17:36:24 +02:00
refractionpcsx2 c0e325dfbf GS-HW: Correct FBMask masks for texture shuffles 2022-08-06 12:35:16 +01:00
JordanTheToasterandrefractionpcsx2 62e775b7c2 GameDB: Correct The Incredible Hulks name
Corrects the name of the PAL version of The Incredible Hulk and adds missing demo version to the db
2022-08-06 11:52:44 +01:00
BreakPointsandGitHub 37676a296a UI: Update all sizes of App Icon (#6785) 2022-08-06 10:12:52 +01:00
Connor McLaughlinandrefractionpcsx2 bcc4548f7b GS/HW: Clamp draw rect to unscaled, not scaled coordinates
Fixes broken shuffle effect in Haunting Ground when upscale is set above
1x.
2022-08-06 06:13:30 +01:00
JordanTheToasterandlightningterror 60714b5ca4 Qt Updater: Fix use of old icons
Fixes the updater seemingly using the old style of PCSX2 icon.
2022-08-06 00:13:59 +02:00
Mrlinkwiiandrefractionpcsx2 d632634e56 Gamedb: add basic mipmap to Blood Omen 2 2022-08-05 19:17:14 +01:00
lightningterror bec8b40edb GS-wx: Remove some unused upscale code for renderer tab. 2022-08-05 11:41:29 +02:00
lightningterror ab361eef72 GS-wx: Fix Wunused-but-set-variable warning. 2022-08-05 11:37:50 +02:00
Connor McLaughlinandrefractionpcsx2 1f16adbca7 GS/Vulkan: Don't use clear attachments on cleared RT/DS
Redundant.
2022-08-05 07:16:53 +01:00
Connor McLaughlinandrefractionpcsx2 1677ef3189 GS/TextureCache: Elide copies when source matches target
Assuming everything matches up, instead of copying the target, we can just sample it directly.
It's the same as doing the copy first, except we save GPU time.
2022-08-05 07:16:53 +01:00
Connor McLaughlinandrefractionpcsx2 36defdfbe9 GS: Use tex-is-fb for sprites/shuffles 2022-08-05 07:16:53 +01:00
Mrlinkwiiandrefractionpcsx2 7ba6e4adc3 Gamedb: remove not needed upscaling fixes for God of war 2022-08-05 00:19:55 +01:00
TheLastRarandlightningterror ee2cbc80b8 DEV9: Sockets: Set Arp Hardware Type 2022-08-03 21:05:40 +02:00
lightningterror b4d960e795 GS-ogl: Remove bad driver messages for intel/amd.
AMD has new gl drivers which work well now.
For intel it's not really needed as the log may be useful for broadwell or lower igpu.
2022-08-03 20:57:47 +02:00
lightningterror 0f716d9053 GS-hw: Fix dithering log. 2022-08-03 20:54:30 +02:00
JordanTheToasterandrefractionpcsx2 cdbfd22296 GameDB: Corrects name of Asterix & Obelix XXL2
Fixes the incorrect name of Asterix & Obelix XXL
2022-08-03 19:34:10 +01:00
Goatman13andlightningterror de801a4f23 GameDB: Replace Evolution Snowboarding patches.
Instead of skipping videos, patches extend stack in problematic function. So required data is no longer overwritten. Workaround for missing EE data cache emulation.
2022-08-03 11:46:51 +02:00
JordanTheToasterandrefractionpcsx2 1376a615b7 GameDB: Misc compat level fixes
Fixes some out of date compat levels
2022-08-03 09:51:23 +01:00
noigeaRandrefractionpcsx2 1fbc9ab85e GameDB: add Panzer Elite Action upscaling fix 2022-08-03 09:51:00 +01:00
refractionpcsx2 9a8a3601a7 UI-Qt: Add Bilinear dropdown to SW options 2022-08-02 23:35:48 +01:00
refractionpcsx2 f1e68e9bd0 GS: Don't double res on No-Interlace patch when interlaced 2022-08-02 23:35:35 +01:00
icheeandrefractionpcsx2 5228e6e6c7 GameDB: Fixes Dual Hearts FMV's not being deinterlaced
Deinterlacing is not being applied causing the FMV's to be offset. This forces blend tff.

Fixes #6715.
2022-08-02 11:36:24 +01:00
PCSX2 Botandlightningterror 5b977cef54 PAD: Update to latest controller database. 2022-08-01 23:43:45 +02:00
refractionpcsx2 a802deeb51 GameDB: Add round sprite full for DMC3, reduces blur. 2022-08-01 21:07:30 +01:00
JordanTheToasterandrefractionpcsx2 eaf6375410 GameDB: Maximo vs Army of Zin Fixes
Adds fixes and adds a missing entry in the DB for the Korean version.
2022-08-01 16:54:00 +01:00
JordanTheToasterandrefractionpcsx2 d1daf21a3f GameDB: Misc fixes
Fixes many problems with many games and adds missing hacks and fixes.
2022-08-01 14:02:13 +01:00
Risaeandrefractionpcsx2 98c83c8509 GameDB: Add fixes for Growlanser V & Growlanser VI 2022-08-01 09:02:10 +01:00
Mrlinkwiiandrefractionpcsx2 b25731f621 Gamedb:upscaling fixes for "dot hack Infection Part 1" 2022-07-31 19:50:01 +01:00
Mrlinkwiiandrefractionpcsx2 563f5ec713 Gamedb: add partial preload to "Hitman Contracts" 2022-07-31 12:36:48 +01:00
refractionpcsx2 ad25ae43d5 GameDB: Disable Instant VU for Juiced 2022-07-31 10:58:51 +01:00
refractionpcsx2 b058e72fdd VIF: Wait for VU on flush + clang format
Improves performance in MTVU + Non-instant a little.
2022-07-31 10:58:51 +01:00
refractionpcsx2 38ee8ccfe3 VU: Fix some bugs, ignore VU's in EE Timing Hack 2022-07-31 10:58:51 +01:00
refractionpcsx2 53161f76a6 VU-MTVU: Simulate VU times when in MTVU w/o Instant VU. 2022-07-31 10:58:51 +01:00
Connor McLaughlinandrefractionpcsx2 742a929966 GS: Purge sparse texture
Only worked on a limited number of drivers, not reliable, and not
necessary now that we're reducing target sizes, which works better
anyway.
2022-07-31 10:58:39 +01:00
Connor McLaughlinandrefractionpcsx2 63b3646e73 GS/TextureCache: Expand perfect-matched targets for display when needed
Hitman Contracts draws a line near the bottom of the screen, presumably
with a smaller scissor, then scans out 448 lines. Which meant the merge
oversampled and smeared.
2022-07-31 10:39:35 +01:00
refractionpcsx2 794c73a613 GS-debug: Fix GSDumps when rt or ds is null. 2022-07-31 08:21:22 +01:00
JordanTheToasterandrefractionpcsx2 59fc2a4c15 GameDB: WRC 4 Fixes
Fixes misaligned text and car shadow softness.
2022-07-30 22:15:44 +01:00
Connor McLaughlinandrefractionpcsx2 6a144f86cf GS: Improve target size calcs and remove conservative framebuffer 2022-07-30 17:16:59 +01:00
refractionpcsx2 f218e11d78 GS: Rearrange GS Dump names to be less annoying to navigate 2022-07-30 17:16:35 +01:00
JordanTheToasterandrefractionpcsx2 f6bcd8a2c2 GameDB: Various texture preloading fixes
Fixes performance problems when texture preloading is set to Full (Hash Cache).
2022-07-30 17:08:23 +01:00
JordanTheToasterandrefractionpcsx2 bf0cd5a6cd Qt: Recommended text fixes
Fixes some missing or incorrect recommended boxes.
2022-07-29 13:42:31 +01:00
tellowkrinkle fc1504f2e5 GHActions: Properly label Linux AVX2/SSE4 releases 2022-07-28 20:45:23 -05:00
Stuart Kennyandrefractionpcsx2 7b4d545dca GameDB: Ridge Racer V upscaling fixes. 2022-07-28 22:27:12 +01:00
JordanTheToasterandrefractionpcsx2 89f27d0b2d Qt: Change cycle skipping text
Changes the cycle skipping default level text from "Normal" to "None".
2022-07-28 20:54:55 +01:00
Anderson_CardosoandGitHub 3728f42185 GUI-Qt: Updated Controller Image (#6729) 2022-07-28 11:52:03 +01:00
lightningterror 2d6c4c6aee GameDB: Change halfPixelOffset normal to special for shadow hearts series.
Normal breaks shadows.
2022-07-28 12:47:14 +02:00
lightningterrorandGitHub 83b8ec6a99 cheats_ni: Cleanup no interlace patches. (#6717)
Remove widescreen, blur, and other crap patches that shouldn't be here.
Affected crcs 1F34E107,14DDB291,71B142EC,586EA828,64328775,A8D83239
2022-07-27 14:04:16 +02:00
JordanandGitHub 5e87f6d806 GameDB: Energy Airforce fixes (#6714)
Adds autoflush to Energy Airforce Aim Strike.
2022-07-26 18:50:27 +02:00
Mrlinkwiiandrefractionpcsx2 f2da932777 GameDB: Correct title for Mushihimesama 2022-07-26 13:10:30 +01:00
refractionpcsx2 4b3e6d7a58 GS: Flush any pending draws on reset. 2022-07-25 22:04:16 +01:00
Mrlinkwiiandrefractionpcsx2 c50d671bdb GameDB: add 'VUSyncHack' to Air Ranger - Rescue Helicopter 2022-07-25 19:57:33 +01:00
PCSX2 Botandlightningterror 5290cbea94 PAD: Update to latest controller database. 2022-07-25 18:12:34 +02:00
Connor McLaughlinandrefractionpcsx2 f6b55a4e19 GS/Vulkan: Fix incorrect render pass for stencil DATE 2022-07-25 14:33:09 +01:00
1289 changed files with 240135 additions and 430230 deletions
+2
View File
@@ -1,3 +1,5 @@
---
exclude_paths:
- '3rdparty/**'
- '*.md'
- '**/*.md'
+5 -1
View File
@@ -26,13 +26,17 @@ The following is a list of *general* style recommendations that will make review
* Please try to prefix your commit message, indicating what area of the project was modified.
* For example `gs: message...`.
* Looking at the project's commit history will help with keeping prefixes consistent overtime, *there is no strictly enforced list*.
* Try to keep messages brief and informative
* Remove unnecessary commits and squash commits together when appropriate.
* If you are not familiar with rebasing with git, check out the following resources:
* CLI - https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history
* GUI (SourceTree) - https://www.atlassian.com/blog/sourcetree/interactive-rebase-sourcetree
* Code Styling and Formatting
* [Consult the style guide](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
* Run `clang-format` using the configuration file in the root of the repository
* Visual Studio Setup - https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/
* IMPORTANT - if you are running `clang-format` on unrelated changes (ie. formatting an entire file), please do so in a separate commit.
@@ -41,9 +45,9 @@ The following is a list of *general* style recommendations that will make review
## General Documentation And Coding Strategies
* [Commenting Etiquette](https://github.com/PCSX2/pcsx2/wiki/Commenting-Etiquette)
* [Coding style](https://github.com/PCSX2/pcsx2/wiki/Code-Formatting-Guidelines)
* [More comprehensive style-guide (Currently in Draft)](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
* [wxWidgets coding strategies](https://github.com/PCSX2/pcsx2/wiki/wxWidgets-Coding-Strategies)
## Tasks
-1
View File
@@ -12,7 +12,6 @@
- 'cmake/**/*'
- 'CMakeLists.txt'
- '**/CMakeLists.txt'
- 'buildbot.xml'
- 'build.sh'
'Dependencies':
- '3rdparty/*'
+2 -5
View File
@@ -21,12 +21,9 @@ jobs:
uses: actions/checkout@v3
- name: Validate Contents
env:
GAMEDB_PATH: ./bin/resources/GameIndex.yaml
SCRIPT_DIR: .github/workflows/scripts/lint/gamedb
run: |
pip install -r "${SCRIPT_DIR}/requirements.txt"
python "${SCRIPT_DIR}/lint.py"
npm install -g ajv-cli
ajv validate -s ./pcsx2/Docs/gamedb-schema.json --spec=draft2020 -d ./bin/resources/GameIndex.yaml
- name: Check Formatting
run: |
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
with:
jobName: "with LTO"
compiler: gcc
cmakeflags: "-DLTO_PCSX2_CORE=ON"
cmakeflags: "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON"
buildAppImage: true
secrets: inherit
+10 -4
View File
@@ -32,6 +32,10 @@ on:
required: false
type: string
default: ""
cheats_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
jobs:
build_linux:
@@ -69,10 +73,7 @@ jobs:
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
- name: ccache cache files
uses: actions/cache@v3
@@ -97,6 +98,11 @@ jobs:
if: steps.cache-deps.outputs.cache-hit != 'true'
run: .github/workflows/scripts/linux/build-dependencies-qt.sh
- name: Download cheats
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
- name: Generate CMake
env:
COMPILER: ${{ inputs.compiler }}
+12 -6
View File
@@ -9,7 +9,7 @@ on:
os:
required: false
type: string
default: ubuntu-18.04
default: ubuntu-20.04
platform:
required: false
type: string
@@ -28,6 +28,10 @@ on:
required: false
type: string
default: ""
cheats_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
jobs:
build_linux:
@@ -41,7 +45,7 @@ jobs:
CCACHE_COMPRESS: true
CCACHE_COMPRESSLEVEL: 9
CCACHE_MAXSIZE: 100M
SDL: SDL2-2.0.22
SDL: SDL2-2.26.0
PATCHELF_VERSION: 0.12
steps:
@@ -67,10 +71,7 @@ jobs:
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
- name: ccache cache files
uses: actions/cache@v3
@@ -115,6 +116,11 @@ jobs:
fi
sudo make -C 3rdparty/${{ env.SDL }} install
- name: Download cheats
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
- name: Generate CMake
env:
PLATFORM: ${{ inputs.platform }}
+55 -10
View File
@@ -17,6 +17,10 @@ on:
gui:
required: true
type: string
cheats_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
jobs:
build_macos:
@@ -26,11 +30,11 @@ jobs:
timeout-minutes: 90
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
BUILDCACHE_COMPRESS_FORMAT: ZSTD
BUILDCACHE_COMPRESS_LEVEL: 9
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
BUILDCACHE_DIRECT_MODE: true
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
CCACHE_COMPRESSLEVEL: 9
CCACHE_MAXSIZE: 100M
steps:
- name: Checkout Repository
@@ -58,11 +62,12 @@ jobs:
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_ANALYTICS: 1
run: |
brew unlink libjpeg libpng # Conflicts with our self-built dependencies
brew unlink libjpeg || true # Conflicts with our self-built dependencies
brew unlink libpng || true
# Unlike other packages, brew's MoltenVK build uses MoltenVK's minimum macOS version of 10.13 so we can use it
if ! brew install molten-vk; then
if ! brew install molten-vk ccache; then
brew update
brew install molten-vk
brew install molten-vk ccache
fi
- name: Cache Dependencies
@@ -78,14 +83,54 @@ jobs:
GUI: ${{ inputs.gui }}
run: .github/workflows/scripts/macos/build-dependencies.sh
- name: Download cheats
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
- name: Cache ccache cache
uses: actions/cache@v3
with:
path: .ccache
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.gui }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.gui }} ccache
- name: Generate CMake Files
run: |
QT_BUILD=$([ "${{ inputs.gui }}" == "Qt" ] && echo "ON" || echo "OFF")
cmake -DCMAKE_PREFIX_PATH="$HOME/deps" -DCMAKE_BUILD_TYPE=Release -DQT_BUILD="$QT_BUILD" -DUSE_OPENGL=OFF -DDISABLE_ADVANCE_SIMD=ON -DLTO_PCSX2_CORE=ON -DUSE_SYSTEM_LIBS=OFF -DUSE_SYSTEM_SDL2=ON -B build .
cmake -DCMAKE_PREFIX_PATH="$HOME/deps" \
-DCMAKE_BUILD_TYPE=Release \
-DQT_BUILD="$QT_BUILD" \
-DUSE_OPENGL=OFF \
-DDISABLE_ADVANCE_SIMD=ON \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DUSE_SYSTEM_LIBS=OFF \
-DUSE_SYSTEM_SDL2=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
-B build .
- name: Build PCSX2
working-directory: build
run: make -j$(getconf _NPROCESSORS_ONLN) # macOS doesn't use make install
run: |
ccache -p
ccache -s
ccache -z
make -j$(getconf _NPROCESSORS_ONLN) # macOS doesn't use make install
ccache -s
# Ensure there's no global constructors in multi-isa files
for dir in */CMakeFiles/GS-{avx,avx2}.dir; do
if find "$dir" -name "*.o" | xargs nm | grep _GLOBAL_; then
echo "::error::Multi-isa files must not have global constructors!"
exit 1
fi
done
- name: Run Tests
working-directory: build
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
# Docs - https://github.com/mathieudutour/github-tag-action
- name: Bump Version and Push Tag
id: tag_version
uses: mathieudutour/github-tag-action@v6.0
uses: mathieudutour/github-tag-action@v6.1
with:
# Workflows cannot trigger other workflows implicitly
# - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
with:
jobName: "wxWidgets"
compiler: gcc
cmakeflags: "-DLTO_PCSX2_CORE=ON"
cmakeflags: "-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON"
buildAppImage: true
secrets: inherit
@@ -21,7 +21,7 @@ NAME=""
if [ "${OS}" == "macos" ]; then
NAME="PCSX2-${OS}-${GUI_FRAMEWORK}"
elif [[ "${OS}" == "windows" || ("$OS" == "linux" && "$GUI_FRAMEWORK" == "QT") ]]; then
elif [[ ("${OS}" == "windows" && "$BUILD_SYSTEM" != "cmake") || ("$OS" == "linux" && "$GUI_FRAMEWORK" == "QT") ]]; then
NAME="PCSX2-${OS}-${GUI_FRAMEWORK}-${ARCH}-${SIMD}"
else
NAME="PCSX2-${OS}-${GUI_FRAMEWORK}-${ARCH}"
@@ -54,4 +54,4 @@ fi
# Trim the Name
NAME=$(printf "%.199s]" "$NAME")
echo "${NAME}"
echo "##[set-output name=artifact-name;]${NAME}"
echo "artifact-name=${NAME}" >> "$GITHUB_OUTPUT"
@@ -1,270 +0,0 @@
import os
import yaml
# Assumes this is ran from the root of the repository
file_path = os.environ['GAMEDB_PATH']
# These settings have to be manually kept in sync with the emulator code unfortunately.
# up to date validation should ALWAYS be provided via the application!
allowed_game_options = [
"name",
"region",
"compat",
"roundModes",
"clampModes",
"gameFixes",
"gsHWFixes",
"speedHacks",
"memcardFilters",
"patches",
]
allowed_round_modes = ["eeRoundMode", "vuRoundMode"]
allowed_clamp_modes = ["eeClampMode", "vuClampMode"]
allowed_game_fixes = [
"FpuMulHack",
"FpuNegDivHack",
"GoemonTlbHack",
"SoftwareRendererFMVHack",
"SkipMPEGHack",
"OPHFlagHack",
"EETimingHack",
"DMABusyHack",
"GIFFIFOHack",
"VIFFIFOHack",
"VIF1StallHack",
"VuAddSubHack",
"IbitHack",
"VUSyncHack",
"VUOverflowHack",
"XGKickHack",
"BlitInternalFPSHack",
]
allowed_gs_hw_fixes = [
"autoFlush",
"conservativeFramebuffer",
"cpuFramebufferConversion",
"disableDepthSupport",
"wrapGSMem",
"preloadFrameData",
"disablePartialInvalidation",
"textureInsideRT",
"alignSprite",
"mergeSprite",
"wildArmsHack",
"pointListPalette",
"mipmap",
"trilinearFiltering",
"skipDrawStart",
"skipDrawEnd",
"halfBottomOverride",
"halfPixelOffset",
"roundSprite",
"texturePreloading",
"deinterlace",
"cpuSpriteRenderBW",
]
gs_hw_fix_ranges = {
"mipmap": (0, 2),
"trilinearFiltering": (0, 2),
"skipDrawStart": (0, 100000),
"skipDrawEnd": (0, 100000),
"halfPixelOffset": (0, 3),
"roundSprite": (0, 2),
"deinterlace": (0, 7),
"cpuSpriteRenderBW": (1, 10),
}
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack", "MTVUSpeedHack"]
# Patches are allowed to have a 'default' key or a crc-32 key, followed by
allowed_patch_options = ["author", "content"]
issue_list = []
def is_hex_number(string):
try:
int(string, 16)
return True
except Exception:
return False
def validate_string_option(serial, key, value):
if not isinstance(value, str):
issue_list.append("[{}]: '{}' must be a string".format(serial, key))
def validate_int_option(serial, key, value, low, high):
if not isinstance(value, int) or (value < low or value > high):
issue_list.append(
"[{}]: '{}' must be an int and between {}-{} (inclusive)".format(
serial, key, low, high
)
)
def validate_list_of_strings(serial, key, value):
if not isinstance(value, list) or not all(isinstance(item, str) for item in value):
issue_list.append("[{}]: '{}' must be a list of strings".format(serial, key))
def validate_valid_options(serial, key, value, allowed_values):
if value not in allowed_values:
issue_list.append("[{}]: Invalid '{}' option [{}]".format(serial, key, value))
def validate_clamp_round_modes(serial, key, value, allowed_values):
if not isinstance(value, dict):
issue_list.append("[{}]: '{}' must be a valid object".format(serial, key))
return
for mode_key, mode_value in value.items():
validate_valid_options(serial, key, mode_key, allowed_values)
validate_int_option(serial, key, mode_value, 0, 3)
def validate_game_fixes(serial, key, value):
if not isinstance(value, list):
issue_list.append(
"[{}]: 'gameFixes' must be a list of valid gameFixes".format(serial)
)
return
for gamefix in value:
validate_valid_options(serial, key, gamefix, allowed_game_fixes)
def validate_gs_hw_fix_value(serial, key, value):
low, high = 0, 1
if key in gs_hw_fix_ranges:
low, high = gs_hw_fix_ranges[key]
validate_int_option(serial, key, value, low, high)
def validate_gs_hw_fixes(serial, key, value):
if not isinstance(value, dict):
issue_list.append("[{}]: 'gsHWFixes' must be a valid object".format(serial))
return
for fix, fix_value in value.items():
validate_valid_options(serial, key, fix, allowed_gs_hw_fixes)
validate_gs_hw_fix_value(serial, fix, fix_value)
# skipdraw range must have end >= start
skip_draw_start = value["skipDrawStart"] if "skipDrawStart" in value else 0
skip_draw_end = value["skipDrawEnd"] if "skipDrawEnd" in value else 0
if isinstance(skip_draw_start, int) and isinstance(skip_draw_end, int) and skip_draw_end < skip_draw_start:
issue_list.append("[{}]: skipDrawStart({}) must be greater or equal to skipDrawEnd({})".format(
serial, skip_draw_start, skip_draw_end))
def validate_speed_hacks(serial, key, value):
if not isinstance(value, dict):
issue_list.append("[{}]: 'speedHacks' must be a valid object".format(serial))
return
for speedhack, speedhack_value in value.items():
validate_valid_options(serial, key, speedhack, allowed_speed_hacks)
validate_int_option(serial, speedhack, speedhack_value, 0, 1)
def validate_patches(serial, key, value):
if not isinstance(value, dict):
issue_list.append(
"[{}]: 'patches' must be valid mapping of CRC32 -> Patch Objects".format(
serial
)
)
return
for crc, patch in value.items():
if crc != "default" and not is_hex_number(str(crc)):
issue_list.append(
"[{}]: Patches must either be key'd with 'default' or a valid CRC-32 Hex String".format(
serial
)
)
continue
for patch_option, option_value in patch.items():
validate_valid_options(serial, key, patch_option, allowed_patch_options)
if patch_option == "author":
validate_string_option(serial, patch_option, option_value)
if patch_option == "content":
validate_string_option(serial, patch_option, option_value)
# pylint:disable=unnecessary-lambda
option_validation_handlers = {
"name": (lambda serial, key, value: validate_string_option(serial, key, value)),
"region": (lambda serial, key, value: validate_string_option(serial, key, value)),
"compat": (
lambda serial, key, value: validate_int_option(serial, key, value, 0, 6)
),
"roundModes": (
lambda serial, key, value: validate_clamp_round_modes(
serial, key, value, allowed_round_modes
)
),
"clampModes": (
lambda serial, key, value: validate_clamp_round_modes(
serial, key, value, allowed_clamp_modes
)
),
"gameFixes": (lambda serial, key, value: validate_game_fixes(serial, key, value)),
"gsHWFixes": (lambda serial, key, value: validate_gs_hw_fixes(serial, key, value)),
"speedHacks": (lambda serial, key, value: validate_speed_hacks(serial, key, value)),
"memcardFilters": (
lambda serial, key, value: validate_list_of_strings(serial, key, value)
),
"patches": (lambda serial, key, value: validate_patches(serial, key, value)),
}
class UniqueKeyLoader(yaml.FullLoader):
def construct_mapping(self, node, deep=False):
mapping = set()
for key_node, _ in node.value:
key = self.construct_object(key_node, deep=deep)
if key in mapping:
raise ValueError(f"Duplicate {key!r} key found in YAML.")
mapping.add(key)
return super().construct_mapping(node, deep)
print("Opening {}...".format(file_path))
with open(file_path, encoding="utf-8") as f:
try:
print("Attempting to parse GameDB file...")
gamedb = yaml.load(f, Loader=UniqueKeyLoader)
except Exception as err:
print(err)
print(
"Unable to parse GameDB. Exiting, verify that the file indeed is valid YAML."
)
exit(1)
print("File loaded successfully, validating schema...")
progress_counter = 0
for serial, game_options in gamedb.items():
progress_counter = progress_counter + 1
if progress_counter % 500 == 0 or progress_counter >= len(gamedb.items()):
print(
"[{}/{}] Processing GameDB Entries...".format(
progress_counter, len(gamedb.items())
)
)
# Check for required values
if not "name" in game_options.keys():
issue_list.append("[{}]: 'name' is a required value".format(serial))
if not "region" in game_options.keys():
issue_list.append("[{}]: 'region' is a required value".format(serial))
# Check the options
for key, value in game_options.items():
if key not in allowed_game_options:
issue_list.append("[{}]: Invalid option [{}]".format(serial, key))
continue
if key in option_validation_handlers:
option_validation_handlers[key](serial, key, value)
if len(issue_list) > 0:
print("Issues found during validation:")
print(*issue_list, sep="\n")
exit(1)
else:
print("GameDB Validated Successfully!")
exit(0)
@@ -1 +0,0 @@
PyYAML==5.4.1
+2 -2
View File
@@ -1,4 +1,4 @@
#!/bin/sh
cd "$(dirname "$0")"
exec ./usr/bin/pcsx2-qt "$@"
APPDIR=$(dirname "$0")
exec "$APPDIR/usr/bin/pcsx2-qt" "$@"
@@ -10,7 +10,7 @@ fi
export BINARY_NAME=$(basename "$ARGV0")
if [[ ! -e "$PWD/$BINARY_NAME.config" ]]; then
mkdir "$PWD/$BINARY_NAME.config"
fi
fi
export XDG_CONFIG_HOME="$PWD/$BINARY_NAME.config"
mkdir -p "$HOME"/.local/share/icons/hicolor/scalable/apps && cp "$APPDIR"/PCSX2.png "$HOME"/.local/share/icons/hicolor/scalable/apps
+39 -1
View File
@@ -90,6 +90,7 @@ declare -a SYSLIBS=(
"libxkbcommon.so.0"
"libxkbcommon-x11.so.0"
"pulseaudio/libpulsecommon-13.99.so"
"libasound.so.2"
"libfreetype.so.6"
"libpcre2-16.so.0"
"libexpat.so.1"
@@ -118,6 +119,42 @@ declare -a SYSLIBS=(
"libpng16.so.16"
"libudev.so.1"
"libuuid.so.1"
"libcurl.so.4"
"libnghttp2.so.14"
"libidn2.so.0"
"librtmp.so.1"
"libssh.so.4"
"libpsl.so.5"
"libssl.so.1.1"
"libnettle.so.7"
"libgnutls.so.30"
"libgssapi_krb5.so.2"
"libldap_r-2.4.so.2"
"liblber-2.4.so.2"
"libbrotlidec.so.1"
"libunistring.so.2"
"libhogweed.so.5"
"libgmp.so.10"
"libp11-kit.so.0"
"libtasn1.so.6"
"libkrb5.so.3"
"libk5crypto.so.3"
"libcom_err.so.2"
"libkrb5support.so.0"
"libsasl2.so.2"
"libgssapi.so.3"
"libbrotlicommon.so.1"
"libkeyutils.so.1"
"libheimntlm.so.0"
"libkrb5.so.26"
"libasn1.so.8"
"libhcrypto.so.4"
"libroken.so.18"
"libwind.so.0"
"libheimbase.so.1"
"libhx509.so.5"
"libsqlite3.so.0"
"libcrypt.so.1"
)
declare -a DEPLIBS=(
@@ -143,6 +180,7 @@ declare -a QTPLUGINS=(
"plugins/imageformats"
"plugins/platforms"
#"plugins/platformthemes" # Enable this if we want to ship GTK+ themes at any point.
"plugins/tls"
"plugins/wayland-decoration-client"
"plugins/wayland-graphics-integration-client"
"plugins/wayland-graphics-integration-server"
@@ -165,7 +203,7 @@ mkdir "$OUTDIR"
mkdir -p "$OUTDIR/usr/bin" "$OUTDIR/usr/lib" "$OUTDIR/usr/lib/pulseaudio"
echo "Copying binary and resources..."
cp -a "$BINDIR/$BINARY" "$BINDIR/resources" "$BINDIR/shaders" "$OUTDIR/usr/bin"
cp -a "$BINDIR/$BINARY" "$BINDIR/resources" "$OUTDIR/usr/bin"
# Don't need old wx locales.
rm -fr "$OUTDIR/usr/bin/resources/locale"
+1 -1
View File
@@ -23,7 +23,7 @@ sudo cp /usr/local/bin/patchelf /tmp/squashfs-root/usr/bin/patchelf
cd "$GITHUB_WORKSPACE"
ninja -C build install
cp ./pcsx2/gui/Resources/AppIcon64.png ./squashfs-root/PCSX2.png
cp ./linux_various/PCSX2.desktop.in ./squashfs-root/PCSX2.desktop
cp ./linux_various/PCSX2.desktop.in ./squashfs-root/PCSX2.desktop
sed -i -e 's|Categories=@PCSX2_MENU_CATEGORIES@|Categories=Game;Emulator;|g' ./squashfs-root/PCSX2.desktop
sed -i -e 's|__GL_THREADED_OPTIMIZATIONS=1|__GL_THREADED_OPTIMIZATIONS=0|g' ./squashfs-root/PCSX2.desktop
curl -sSfL "https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-$APPARCH" -o ./squashfs-root/runtime
@@ -4,14 +4,14 @@ set -e
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.0.22
SDL=SDL2-2.26.0
QT=6.3.1
mkdir -p deps-build
cd deps-build
cat > SHASUMS <<EOF
fe7cbf3127882e3fc7259a75a0cb585620272c51745d3852ab9dd87960697f2e $SDL.tar.gz
8000d7169febce93c84b6bdf376631f8179132fd69f7015d4dadb8b9c2bdb295 $SDL.tar.gz
0a64421d9c2469c2c48490a032ab91d547017c9cc171f3f8070bc31888f24e03 qtbase-everywhere-src-$QT.tar.xz
7b19f418e6f7b8e23344082dd04440aacf5da23c5a73980ba22ae4eba4f87df7 qtsvg-everywhere-src-$QT.tar.xz
c412750f2aa3beb93fce5f30517c607f55daaeb7d0407af206a8adf917e126c1 qttools-everywhere-src-$QT.tar.xz
@@ -47,7 +47,7 @@ tar xf "qtbase-everywhere-src-$QT.tar.xz"
cd "qtbase-everywhere-src-$QT"
mkdir build
cd build
../configure -prefix "$INSTALLDIR" -release -no-dbus -gui -widgets -fontconfig -qt-doubleconversion -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -- -DFEATURE_dbus=OFF -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF
../configure -prefix "$INSTALLDIR" -release -no-dbus -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -- -DFEATURE_dbus=OFF -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF
cmake --build . --parallel
cmake --install .
cd ../../
@@ -35,7 +35,9 @@ declare -a BUILD_PACKAGES=(
# Packages - PCSX2
declare -a PCSX2_PACKAGES=(
"libaio-dev"
"libasound2-dev"
"libbz2-dev"
"libcurl4-openssl-dev"
"libegl1-mesa-dev"
"libgl1-mesa-dev"
"libgtk-3-dev"
@@ -12,6 +12,7 @@ declare -a BUILD_PACKAGES=(
# Packages - PCSX2
declare -a PCSX2_PACKAGES=(
"libaio-dev"
"libasound2-dev"
"libbz2-dev"
"libegl1-mesa-dev"
"libgdk-pixbuf2.0-dev"
@@ -9,11 +9,9 @@ else
fi
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.0.22
SDL=SDL2-2.26.0
PNG=1.6.37
JPG=9e
SAMPLERATE=libsamplerate-0.1.9
PORTAUDIO=pa_stable_v190700_20210406
SOUNDTOUCH=soundtouch-2.3.1
WXWIDGETS=3.1.6
QT=6.3.1
@@ -27,11 +25,9 @@ export CFLAGS="-I$INSTALLDIR/include -Os $CFLAGS"
export CXXFLAGS="-I$INSTALLDIR/include -Os $CXXFLAGS"
cat > SHASUMS <<EOF
fe7cbf3127882e3fc7259a75a0cb585620272c51745d3852ab9dd87960697f2e $SDL.tar.gz
8000d7169febce93c84b6bdf376631f8179132fd69f7015d4dadb8b9c2bdb295 $SDL.tar.gz
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-$PNG.tar.xz
4077d6a6a75aeb01884f708919d25934c93305e49f7e3f36db9129320e6f4f3d jpegsrc.v$JPG.tar.gz
0a7eb168e2f21353fb6d84da152e4512126f7dc48ccb0be80578c565413444c1 $SAMPLERATE.tar.gz
47efbf42c77c19a05d22e627d42873e991ec0c1357219c0d74ce6a2948cb2def $PORTAUDIO.tgz
6900996607258496ce126924a19fe9d598af9d892cf3f33d1e4daaa9b42ae0b1 $SOUNDTOUCH.tar.gz
4980e86c6494adcd527a41fc0a4e436777ba41d1893717d7b7176c59c2061c25 wxWidgets-$WXWIDGETS.tar.bz2
0a64421d9c2469c2c48490a032ab91d547017c9cc171f3f8070bc31888f24e03 qtbase-everywhere-src-$QT.tar.xz
@@ -44,8 +40,6 @@ curl -L \
-O "https://libsdl.org/release/$SDL.tar.gz" \
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$PNG/libpng-$PNG.tar.xz" \
-O "https://www.ijg.org/files/jpegsrc.v$JPG.tar.gz" \
-O "http://www.mega-nerd.com/SRC/$SAMPLERATE.tar.gz" \
-O "http://files.portaudio.com/archives/$PORTAUDIO.tgz" \
-O "https://www.surina.net/soundtouch/$SOUNDTOUCH.tar.gz" \
-O "https://github.com/wxWidgets/wxWidgets/releases/download/v$WXWIDGETS/wxWidgets-$WXWIDGETS.tar.bz2" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
@@ -79,23 +73,6 @@ make "-j$NPROCS"
make install
cd ..
echo "Installing libsamplerate..."
tar xf "$SAMPLERATE.tar.gz"
cd "$SAMPLERATE"
sed -i "" "s/Carbon.h/Carbon\\/Carbon.h/" examples/audio_out.c
./configure --prefix "$INSTALLDIR" --disable-dependency-tracking --disable-sndfile
make "-j$NPROCS"
make install
cd ..
echo "Installing portaudio..."
tar xf "$PORTAUDIO.tgz"
cd portaudio
./configure --prefix "$INSTALLDIR" --enable-mac-universal=no
make "-j$NPROCS"
make install
cd ..
echo "Installing soundtouch..."
tar xf "$SOUNDTOUCH.tar.gz"
cd "$SOUNDTOUCH"
@@ -118,7 +95,7 @@ if [ "$GUI" == "Qt" ]; then
echo "Installing Qt Base..."
tar xf "qtbase-everywhere-src-$QT.tar.xz"
cd "qtbase-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_optimize_size=ON -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_optimize_size=ON -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF
make -C build "-j$NPROCS"
make -C build install
cd ..
@@ -19,7 +19,12 @@ const embed = new MessageEmbed()
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
);
const webhookClient = new WebhookClient({ url: process.env.DISCORD_BUILD_WEBHOOK });
await webhookClient.send({
embeds: [embed],
});
// Get all webhooks, simple comma-sep string
const webhookUrls = process.env.DISCORD_BUILD_WEBHOOK.split(",");
for (const url of webhookUrls) {
const webhookClient = new WebhookClient({ url: url });
await webhookClient.send({
embeds: [embed],
});
}
@@ -15,13 +15,14 @@ for dir_name in os.listdir(scan_dir):
asset_name += "-linux-AppImage-64bit"
elif "windows" in dir_name.lower():
asset_name += "-windows-64bit"
if "avx" in dir_name.lower():
asset_name += "-AVX2"
else:
asset_name += "-SSE4"
else:
continue;
if "avx2" in dir_name.lower():
asset_name += "-AVX2"
elif "sse4" in dir_name.lower():
asset_name += "-SSE4"
if "wxwidgets" in dir_name.lower():
asset_name += "-wxWidgets"
else:
+11 -2
View File
@@ -58,11 +58,20 @@ jobs:
secrets: inherit
# CMAKE
build_wx_avx2_cmake:
name: "CMake AVX2"
build_wx_sse4_cmake:
name: "CMake SSE4"
uses: ./.github/workflows/windows_build_wx.yml
with:
jobName: wxWidgets
configuration: CMake
buildSystem: cmake
secrets: inherit
build_qt_sse4_cmake:
name: "CMake SSE4"
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: Qt
configuration: CMake
buildSystem: cmake
secrets: inherit
+27 -10
View File
@@ -9,7 +9,7 @@ on:
os:
required: false
type: string
default: windows-2019
default: windows-2022
platform:
required: false
type: string
@@ -28,7 +28,15 @@ on:
qt_binary_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2-windows-dependencies/releases/download/2022-07-24/qt-6.3.1-x64.7z
default: https://github.com/PCSX2/pcsx2-windows-dependencies/releases/download/2022-11-20/qt-6.4.0-x64.7z
qt_dir:
required: false
type: string
default: 3rdparty\qt\6.4.0\msvc2022_64
cheats_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
jobs:
build_windows_qt:
@@ -38,11 +46,6 @@ jobs:
timeout-minutes: 60
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
BUILDCACHE_COMPRESS_FORMAT: ZSTD
BUILDCACHE_COMPRESS_LEVEL: 9
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
BUILDCACHE_DIRECT_MODE: true
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
steps:
- name: Checkout Repository
@@ -77,12 +80,27 @@ jobs:
7z x qt-*-x64.7z
del qt-*-x64.7z
- name: Download cheats
shell: cmd
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
- name: Generate CMake
if: inputs.configuration == 'CMake'
id: cmake
shell: cmd
run: |
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake . -B build "-DCMAKE_PREFIX_PATH=%cd%\${{ inputs.qt_dir }}" -DQT_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DDISABLE_ADVANCE_SIMD=ON -G Ninja
- name: Build PCSX2
shell: cmd
run: |
if "${{ inputs.configuration }}"=="CMake" (
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
cmake --build build --config ${{ steps.cmake.outputs.buildtype }}
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake --build build --config Release || exit /b
cmake --install build --config Release || exit /b
) else (
msbuild "PCSX2_qt.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
)
@@ -102,7 +120,6 @@ jobs:
!./bin/**/*.lib
- name: Upload artifact - with symbols
if: inputs.configuration != 'CMake'
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
+18 -22
View File
@@ -9,7 +9,7 @@ on:
os:
required: false
type: string
default: windows-2019
default: windows-2022
platform:
required: false
type: string
@@ -25,6 +25,10 @@ on:
configuration:
required: true
type: string
cheats_url:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
jobs:
build_windows_wx:
@@ -34,11 +38,6 @@ jobs:
timeout-minutes: 60
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
BUILDCACHE_COMPRESS_FORMAT: ZSTD
BUILDCACHE_COMPRESS_LEVEL: 9
BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
BUILDCACHE_DIRECT_MODE: true
BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log
steps:
- name: Checkout Repository
@@ -61,34 +60,32 @@ jobs:
PR_SHA: ${{ github.event.pull_request.head.sha }}
run: ./.github/workflows/scripts/common/name-artifacts.sh
- name: Setup Buildcache
if: inputs.configuration == 'CMake' # TODO: buildcache on VS
uses: mikehardy/buildcache-action@v1.3.0
with:
cache_key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.configuration }}
- name: Setup msbuild
if: inputs.configuration != 'CMake'
uses: microsoft/setup-msbuild@v1
- name: Download cheats
shell: cmd
run: |
cd bin/resources
aria2c -Z "${{ inputs.cheats_url }}/cheats_ni.zip" "${{ inputs.cheats_url }}/cheats_ws.zip"
- name: Generate CMake
if: inputs.configuration == 'CMake'
id: cmake
shell: cmd
run: |
if "${{ github.event.inputs.retainDebugArtifacts }}"=="true" (SET type=RelWithDebInfo) else (SET type=Release)
if "${{ inputs.platform }}"=="Win32" (SET vcvars=vcvarsamd64_x86.bat) else (SET vcvars=vcvars64.bat)
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\%vcvars%"
echo ::set-output name=buildtype::%type%
echo ::set-output name=vcvars::%vcvars%
cmake . -B build -DCMAKE_BUILD_TYPE=%type% -DLTO_PCSX2_CORE=ON -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_CXX_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\%vcvars%"
echo vcvars=%vcvars%>> %GITHUB_OUTPUT%
cmake . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DDISABLE_ADVANCE_SIMD=ON -G Ninja
- name: Build PCSX2
shell: cmd
run: |
if "${{ inputs.configuration }}"=="CMake" (
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
cmake --build build --config ${{ steps.cmake.outputs.buildtype }}
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
cmake --build build --config Release || exit /b
cp build/pcsx2/pcsx2* bin/
) else (
msbuild "PCSX2_suite.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
@@ -98,8 +95,8 @@ jobs:
if: inputs.configuration == 'CMake'
shell: cmd
run: |
call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
cmake --build build --config ${{ steps.cmake.outputs.buildtype }} --target unittests
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
cmake --build build --config Release --target unittests
- name: Upload artifact
uses: actions/upload-artifact@v3
@@ -116,7 +113,6 @@ jobs:
!./bin/**/*.lib
- name: Upload artifact - with symbols
if: inputs.configuration != 'CMake'
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
+1
View File
@@ -49,6 +49,7 @@ Debug.txt
install_log.txt
padLog.txt
GS_opengl_debug.txt
bad_shader_*
Debug
Release
+3 -6
View File
@@ -14,16 +14,10 @@
path = 3rdparty/wil
url = https://github.com/microsoft/wil.git
branch = master
[submodule "3rdparty/cubeb/cubeb"]
path = 3rdparty/cubeb/cubeb
url = https://github.com/mozilla/cubeb.git
[submodule "3rdparty/rapidyaml/rapidyaml"]
path = 3rdparty/rapidyaml/rapidyaml
url = https://github.com/biojppm/rapidyaml.git
branch = master
[submodule "3rdparty/imgui/imgui"]
path = 3rdparty/imgui/imgui
url = https://github.com/ocornut/imgui.git
[submodule "3rdparty/glslang/glslang"]
path = 3rdparty/glslang/glslang
url = https://github.com/KhronosGroup/glslang.git
@@ -39,3 +33,6 @@
[submodule "3rdparty/zstd/zstd"]
path = 3rdparty/zstd/zstd
url = https://github.com/facebook/zstd.git
[submodule "3rdparty/rcheevos/rcheevos"]
path = 3rdparty/rcheevos/rcheevos
url = https://github.com/RetroAchievements/rcheevos.git
+16
View File
@@ -0,0 +1,16 @@
Matthew Gregan <kinetik@flim.org>
Alexandre Ratchov <alex@caoua.org>
Michael Wu <mwu@mozilla.com>
Paul Adenot <paul@paul.cx>
David Richards <drichards@mozilla.com>
Sebastien Alaiwan <sebastien.alaiwan@gmail.com>
KO Myung-Hun <komh@chollian.net>
Haakon Sporsheim <haakon.sporsheim@telenordigital.com>
Alex Chronopoulos <achronop@gmail.com>
Jan Beich <jbeich@FreeBSD.org>
Vito Caputo <vito.caputo@coreos.com>
Landry Breuil <landry@openbsd.org>
Jacek Caban <jacek@codeweavers.com>
Paul Hancock <Paul.Hancock.17041993@live.com>
Ted Mielczarek <ted@mielczarek.org>
Chun-Min Chang <chun.m.chang@gmail.com>
+300 -9
View File
@@ -1,10 +1,301 @@
# Disable building the stuff we don't need.
set(BUILD_SHARED_LIBS OFF)
set(BUILD_TESTS OFF)
set(BUILD_RUST_LIBS OFF)
set(BUILD_TOOLS OFF)
set(BUNDLE_SPEEX ON)
set(USE_SANITIZERS OFF)
set(LAZY_LOAD_LIBS ON)
# TODO
# - backend selection via command line, rather than simply detecting headers.
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(cubeb
VERSION 0.0.0)
option(BUILD_RUST_LIBS "Build rust backends" OFF)
option(LAZY_LOAD_LIBS "Lazily load shared libraries" ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif()
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (BUILD_RUST_LIBS)
if(EXISTS "${PROJECT_SOURCE_DIR}/src/cubeb-pulse-rs")
set(USE_PULSE_RUST 1)
endif()
if(EXISTS "${PROJECT_SOURCE_DIR}/src/cubeb-coreaudio-rs")
set(USE_AUDIOUNIT_RUST 1)
endif()
endif()
set(CMAKE_CXX_WARNING_LEVEL 4)
if(NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -fno-exceptions -fno-rtti")
else()
string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # Disable RTTI
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # Disable Exceptions
endif()
add_library(cubeb
src/cubeb.c
src/cubeb_mixer.cpp
src/cubeb_resampler.cpp
src/cubeb_log.cpp
src/cubeb_strings.c
src/cubeb_utils.cpp
)
target_include_directories(cubeb
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>
)
set_target_properties(cubeb PROPERTIES
VERSION ${cubeb_VERSION}
SOVERSION ${cubeb_VERSION_MAJOR}
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
)
configure_package_config_file(
"Config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(
FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(TARGETS cubeb EXPORT "${PROJECT_NAME}Targets")
install(
EXPORT "${PROJECT_NAME}Targets"
NAMESPACE "${PROJECT_NAME}::"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
add_library(speex OBJECT subprojects/speex/resample.c)
set_target_properties(speex PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
target_include_directories(speex INTERFACE subprojects)
target_compile_definitions(speex PUBLIC
OUTSIDE_SPEEX
FLOATING_POINT
EXPORT=
RANDOM_PREFIX=speex
)
# $<BUILD_INTERFACE:> required because of https://gitlab.kitware.com/cmake/cmake/-/issues/15415
target_link_libraries(cubeb PRIVATE $<BUILD_INTERFACE:speex>)
include(CheckIncludeFiles)
# Threads needed by cubeb_log, _pulse, _alsa, _jack, _sndio, _oss and _sun
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
target_link_libraries(cubeb PRIVATE Threads::Threads)
if(LAZY_LOAD_LIBS)
check_include_files(pulse/pulseaudio.h USE_PULSE)
check_include_files(alsa/asoundlib.h USE_ALSA)
check_include_files(jack/jack.h USE_JACK)
check_include_files(sndio.h USE_SNDIO)
check_include_files(aaudio/AAudio.h USE_AAUDIO)
if(USE_PULSE OR USE_ALSA OR USE_JACK OR USE_SNDIO OR USE_AAUDIO)
target_link_libraries(cubeb PRIVATE ${CMAKE_DL_LIBS})
endif()
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(libpulse IMPORTED_TARGET libpulse)
if(libpulse_FOUND)
set(USE_PULSE ON)
target_compile_definitions(cubeb PRIVATE DISABLE_LIBPULSE_DLOPEN)
target_link_libraries(cubeb PRIVATE PkgConfig::libpulse)
endif()
pkg_check_modules(alsa IMPORTED_TARGET alsa)
if(alsa_FOUND)
set(USE_ALSA ON)
target_compile_definitions(cubeb PRIVATE DISABLE_LIBASOUND_DLOPEN)
target_link_libraries(cubeb PRIVATE PkgConfig::alsa)
endif()
pkg_check_modules(jack IMPORTED_TARGET jack)
if(jack_FOUND)
set(USE_JACK ON)
target_compile_definitions(cubeb PRIVATE DISABLE_LIBJACK_DLOPEN)
target_link_libraries(cubeb PRIVATE PkgConfig::jack)
endif()
check_include_files(sndio.h USE_SNDIO)
if(USE_SNDIO)
target_compile_definitions(cubeb PRIVATE DISABLE_LIBSNDIO_DLOPEN)
target_link_libraries(cubeb PRIVATE sndio)
endif()
check_include_files(aaudio/AAudio.h USE_AAUDIO)
if(USE_AAUDIO)
target_compile_definitions(cubeb PRIVATE DISABLE_LIBAAUDIO_DLOPEN)
target_link_libraries(cubeb PRIVATE aaudio)
endif()
endif()
if(USE_PULSE)
target_sources(cubeb PRIVATE src/cubeb_pulse.c)
target_compile_definitions(cubeb PRIVATE USE_PULSE)
endif()
if(USE_ALSA)
target_sources(cubeb PRIVATE src/cubeb_alsa.c)
target_compile_definitions(cubeb PRIVATE USE_ALSA)
endif()
if(USE_JACK)
target_sources(cubeb PRIVATE src/cubeb_jack.cpp)
target_compile_definitions(cubeb PRIVATE USE_JACK)
endif()
if(USE_SNDIO)
target_sources(cubeb PRIVATE src/cubeb_sndio.c)
target_compile_definitions(cubeb PRIVATE USE_SNDIO)
endif()
if(USE_AAUDIO)
target_sources(cubeb PRIVATE src/cubeb_aaudio.cpp)
target_compile_definitions(cubeb PRIVATE USE_AAUDIO)
# set this definition to enable low latency mode. Possibly bad for battery
target_compile_definitions(cubeb PRIVATE CUBEB_AAUDIO_LOW_LATENCY)
# set this definition to enable power saving mode. Possibly resulting
# in high latency
# target_compile_definitions(cubeb PRIVATE CUBEB_AAUDIO_LOW_POWER_SAVING)
# set this mode to make the backend use an exclusive stream.
# will decrease latency.
# target_compile_definitions(cubeb PRIVATE CUBEB_AAUDIO_EXCLUSIVE_STREAM)
endif()
check_include_files(AudioUnit/AudioUnit.h USE_AUDIOUNIT)
if(USE_AUDIOUNIT)
target_sources(cubeb PRIVATE
src/cubeb_audiounit.cpp
src/cubeb_osx_run_loop.cpp)
target_compile_definitions(cubeb PRIVATE USE_AUDIOUNIT)
target_link_libraries(cubeb PRIVATE "-framework AudioUnit" "-framework CoreAudio" "-framework CoreServices")
endif()
check_include_files(audioclient.h USE_WASAPI)
if(USE_WASAPI)
target_sources(cubeb PRIVATE
src/cubeb_wasapi.cpp)
target_compile_definitions(cubeb PRIVATE USE_WASAPI)
target_link_libraries(cubeb PRIVATE avrt ole32 ksuser)
endif()
check_include_files("windows.h;mmsystem.h" USE_WINMM)
if(USE_WINMM)
target_sources(cubeb PRIVATE
src/cubeb_winmm.c)
target_compile_definitions(cubeb PRIVATE USE_WINMM)
target_link_libraries(cubeb PRIVATE winmm)
endif()
check_include_files(SLES/OpenSLES.h USE_OPENSL)
if(USE_OPENSL)
target_sources(cubeb PRIVATE
src/cubeb_opensl.c
src/cubeb-jni.cpp)
target_compile_definitions(cubeb PRIVATE USE_OPENSL)
target_link_libraries(cubeb PRIVATE OpenSLES)
endif()
check_include_files(sys/soundcard.h HAVE_SYS_SOUNDCARD_H)
if(HAVE_SYS_SOUNDCARD_H)
try_compile(USE_OSS "${PROJECT_BINARY_DIR}/compile_tests"
${PROJECT_SOURCE_DIR}/cmake/compile_tests/oss_is_v4.c)
if(USE_OSS)
# strlcpy is not available on BSD systems that use glibc,
# like Debian kfreebsd, so try using libbsd if available
include(CheckSymbolExists)
check_symbol_exists(strlcpy string.h HAVE_STRLCPY)
if(NOT HAVE_STRLCPY)
pkg_check_modules(libbsd-overlay IMPORTED_TARGET libbsd-overlay)
if(libbsd-overlay_FOUND)
target_link_libraries(cubeb PRIVATE PkgConfig::libbsd-overlay)
set(HAVE_STRLCPY true)
endif()
endif()
if (HAVE_STRLCPY)
target_sources(cubeb PRIVATE
src/cubeb_oss.c)
target_compile_definitions(cubeb PRIVATE USE_OSS)
endif()
endif()
endif()
check_include_files(android/log.h USE_AUDIOTRACK)
if(USE_AUDIOTRACK)
target_sources(cubeb PRIVATE
src/cubeb_audiotrack.c)
target_compile_definitions(cubeb PRIVATE USE_AUDIOTRACK)
target_link_libraries(cubeb PRIVATE log)
endif()
check_include_files(sys/audioio.h USE_SUN)
if(USE_SUN)
target_sources(cubeb PRIVATE
src/cubeb_sun.c)
target_compile_definitions(cubeb PRIVATE USE_SUN)
endif()
check_include_files(kai.h USE_KAI)
if(USE_KAI)
target_sources(cubeb PRIVATE
src/cubeb_kai.c)
target_compile_definitions(cubeb PRIVATE USE_KAI)
target_link_libraries(cubeb PRIVATE kai)
endif()
if(USE_PULSE AND USE_PULSE_RUST)
include(ExternalProject)
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/rust)
ExternalProject_Add(
cubeb_pulse_rs
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND cargo build COMMAND cargo build --release
BUILD_ALWAYS ON
BINARY_DIR "${PROJECT_SOURCE_DIR}/src/cubeb-pulse-rs"
INSTALL_COMMAND ""
LOG_BUILD ON)
add_dependencies(cubeb cubeb_pulse_rs)
target_compile_definitions(cubeb PRIVATE USE_PULSE_RUST)
target_link_libraries(cubeb PRIVATE
debug "${PROJECT_SOURCE_DIR}/src/cubeb-pulse-rs/target/debug/libcubeb_pulse.a"
optimized "${PROJECT_SOURCE_DIR}/src/cubeb-pulse-rs/target/release/libcubeb_pulse.a" pulse)
endif()
if(USE_AUDIOUNIT AND USE_AUDIOUNIT_RUST)
include(ExternalProject)
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/rust)
ExternalProject_Add(
cubeb_coreaudio_rs
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND cargo build COMMAND cargo build --release
BUILD_ALWAYS ON
BINARY_DIR "${PROJECT_SOURCE_DIR}/src/cubeb-coreaudio-rs"
INSTALL_COMMAND ""
LOG_BUILD ON)
add_dependencies(cubeb cubeb_coreaudio_rs)
target_compile_definitions(cubeb PRIVATE USE_AUDIOUNIT_RUST)
target_link_libraries(cubeb PRIVATE
debug "${PROJECT_SOURCE_DIR}/src/cubeb-coreaudio-rs/target/debug/libcubeb_coreaudio.a"
optimized "${PROJECT_SOURCE_DIR}/src/cubeb-coreaudio-rs/target/release/libcubeb_coreaudio.a")
endif()
add_subdirectory(cubeb)
+4
View File
@@ -0,0 +1,4 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/cubebTargets.cmake")
check_required_components(cubeb)
+45
View File
@@ -0,0 +1,45 @@
# Build instructions for libcubeb
You must have CMake v3.14 or later installed.
1. `git clone --recursive https://github.com/mozilla/cubeb.git`
2. `cd cubeb`
3. `cmake -B ./build .`
4. `cmake --build ./build`
5. `cd build && ctest`
# Windows build notes
Windows builds can use Microsoft Visual Studio 2015, Microsoft Visual Studio
2017, or MinGW-w64 with Win32 threads (by passing `cmake -G` to generate the
appropriate build configuration).
## Microsoft Visual Studio 2015 or 2017 Command Line
CMake can be used from the command line by following the build steps at the top
of this file. CMake will select a default generator based on the environment,
or one can be specified with the `-G` argument.
## Microsoft Visual Studio 2017 IDE
Visual Studio 2017 adds in built support for CMake. CMake can be used from
within the IDE via the following steps:
- Navigate to `File -> Open -> Cmake...`
- Open `CMakeLists.txt` file in the root of the project.
Note, to generate the build in the cubeb dir CMake settings need to be updated
via: `CMake -> Change CMake Settings -> CMakeLists.txt`. The default
configuration used by Visual Studio will place the build in a different location
than the steps detailed at the top of this file.
## MinGW-w64
To build with MinGW-w64, install the following items:
- Download and install MinGW-w64 with Win32 threads.
- Download and install CMake.
- Run MinGW-w64 Terminal from the Start Menu.
- Follow the build steps at the top of this file, but at step 4 run:
`cmake -G "MinGW Makefiles" ../cubeb`
- Continue the build steps at the top of this file.
+13
View File
@@ -0,0 +1,13 @@
Copyright © 2011 Mozilla Foundation
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+7
View File
@@ -0,0 +1,7 @@
[![Build Status](https://github.com/mozilla/cubeb/actions/workflows/build.yml/badge.svg)](https://github.com/mozilla/cubeb/actions/workflows/build.yml)
See INSTALL.md for build instructions.
See [Backend Support](https://github.com/mozilla/cubeb/wiki/Backend-Support) in the wiki for the support level of each backend.
Licensed under an ISC-style license. See LICENSE for details.
+10
View File
@@ -0,0 +1,10 @@
#include <sys/soundcard.h>
#if SOUND_VERSION < 0x040000
# error "OSSv4 is not available in sys/soundcard.h"
#endif
int main()
{
return 0;
}
+14
View File
@@ -0,0 +1,14 @@
SET(CMAKE_SYSTEM_NAME Windows)
set(COMPILER_PREFIX "i686-w64-mingw32")
find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc-posix)
find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++-posix)
SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Submodule 3rdparty/cubeb/cubeb deleted from 773f16b7ea
+36
View File
@@ -0,0 +1,36 @@
{
snd_config_update-malloc
Memcheck:Leak
fun:malloc
...
fun:snd_config_update_r
}
{
snd1_dlobj_cache_get-malloc
Memcheck:Leak
fun:malloc
...
fun:snd1_dlobj_cache_get
}
{
parse_defs-malloc
Memcheck:Leak
fun:malloc
...
fun:parse_defs
}
{
parse_defs-calloc
Memcheck:Leak
fun:calloc
...
fun:parse_defs
}
{
pa_client_conf_from_x11-malloc
Memcheck:Leak
fun:malloc
...
fun:pa_client_conf_from_x11
}
+31 -31
View File
@@ -33,44 +33,44 @@
<ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<PreprocessorDefinitions>USE_WASAPI;USE_WINMM;OUTSIDE_SPEEX;FLOATING_POINT;RANDOM_PREFIX=speex;EXPORT=;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)cubeb\include;$(ProjectDir)cubeb\src;$(ProjectDir)cubeb\subprojects;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)src;$(ProjectDir)subprojects;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp14</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="cubeb\include\cubeb\cubeb.h" />
<ClInclude Include="cubeb\subprojects\speex\arch.h" />
<ClInclude Include="cubeb\subprojects\speex\fixed_generic.h" />
<ClInclude Include="cubeb\subprojects\speex\resample_neon.h" />
<ClInclude Include="cubeb\subprojects\speex\resample_sse.h" />
<ClInclude Include="cubeb\subprojects\speex\speex_config_types.h" />
<ClInclude Include="cubeb\subprojects\speex\speex_resampler.h" />
<ClInclude Include="cubeb\subprojects\speex\stack_alloc.h" />
<ClInclude Include="cubeb\src\cubeb-internal.h" />
<ClInclude Include="cubeb\src\cubeb-speex-resampler.h" />
<ClInclude Include="cubeb\src\cubeb_array_queue.h" />
<ClInclude Include="cubeb\src\cubeb_assert.h" />
<ClInclude Include="cubeb\src\cubeb_log.h" />
<ClInclude Include="cubeb\src\cubeb_mixer.h" />
<ClInclude Include="cubeb\src\cubeb_resampler.h" />
<ClInclude Include="cubeb\src\cubeb_resampler_internal.h" />
<ClInclude Include="cubeb\src\cubeb_ringbuffer.h" />
<ClInclude Include="cubeb\src\cubeb_ring_array.h" />
<ClInclude Include="cubeb\src\cubeb_strings.h" />
<ClInclude Include="cubeb\src\cubeb_utils.h" />
<ClInclude Include="cubeb\src\cubeb_utils_win.h" />
<ClInclude Include="include\cubeb\cubeb.h" />
<ClInclude Include="subprojects\speex\arch.h" />
<ClInclude Include="subprojects\speex\fixed_generic.h" />
<ClInclude Include="subprojects\speex\resample_neon.h" />
<ClInclude Include="subprojects\speex\resample_sse.h" />
<ClInclude Include="subprojects\speex\speex_config_types.h" />
<ClInclude Include="subprojects\speex\speex_resampler.h" />
<ClInclude Include="subprojects\speex\stack_alloc.h" />
<ClInclude Include="src\cubeb-internal.h" />
<ClInclude Include="src\cubeb-speex-resampler.h" />
<ClInclude Include="src\cubeb_array_queue.h" />
<ClInclude Include="src\cubeb_assert.h" />
<ClInclude Include="src\cubeb_log.h" />
<ClInclude Include="src\cubeb_mixer.h" />
<ClInclude Include="src\cubeb_resampler.h" />
<ClInclude Include="src\cubeb_resampler_internal.h" />
<ClInclude Include="src\cubeb_ringbuffer.h" />
<ClInclude Include="src\cubeb_ring_array.h" />
<ClInclude Include="src\cubeb_strings.h" />
<ClInclude Include="src\cubeb_utils.h" />
<ClInclude Include="src\cubeb_utils_win.h" />
<ClInclude Include="include\cubeb_export.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cubeb\src\cubeb.c" />
<ClCompile Include="cubeb\src\cubeb_log.cpp" />
<ClCompile Include="cubeb\src\cubeb_mixer.cpp" />
<ClCompile Include="cubeb\src\cubeb_resampler.cpp" />
<ClCompile Include="cubeb\src\cubeb_strings.c" />
<ClCompile Include="cubeb\src\cubeb_utils.cpp" />
<ClCompile Include="cubeb\src\cubeb_wasapi.cpp" />
<ClCompile Include="cubeb\src\cubeb_winmm.c" />
<ClCompile Include="cubeb\subprojects\speex\resample.c" />
<ClCompile Include="src\cubeb.c" />
<ClCompile Include="src\cubeb_log.cpp" />
<ClCompile Include="src\cubeb_mixer.cpp" />
<ClCompile Include="src\cubeb_resampler.cpp" />
<ClCompile Include="src\cubeb_strings.c" />
<ClCompile Include="src\cubeb_utils.cpp" />
<ClCompile Include="src\cubeb_wasapi.cpp" />
<ClCompile Include="src\cubeb_winmm.c" />
<ClCompile Include="subprojects\speex\resample.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
+30 -30
View File
@@ -1,41 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="cubeb\src\cubeb-internal.h" />
<ClInclude Include="cubeb\src\cubeb-speex-resampler.h" />
<ClInclude Include="cubeb\src\cubeb_array_queue.h" />
<ClInclude Include="cubeb\src\cubeb_assert.h" />
<ClInclude Include="cubeb\src\cubeb_log.h" />
<ClInclude Include="cubeb\src\cubeb_mixer.h" />
<ClInclude Include="cubeb\src\cubeb_resampler.h" />
<ClInclude Include="cubeb\src\cubeb_resampler_internal.h" />
<ClInclude Include="cubeb\src\cubeb_ring_array.h" />
<ClInclude Include="cubeb\src\cubeb_ringbuffer.h" />
<ClInclude Include="cubeb\src\cubeb_strings.h" />
<ClInclude Include="cubeb\src\cubeb_utils.h" />
<ClInclude Include="cubeb\src\cubeb_utils_win.h" />
<ClInclude Include="cubeb\subprojects\speex\fixed_generic.h">
<ClInclude Include="src\cubeb-internal.h" />
<ClInclude Include="src\cubeb-speex-resampler.h" />
<ClInclude Include="src\cubeb_array_queue.h" />
<ClInclude Include="src\cubeb_assert.h" />
<ClInclude Include="src\cubeb_log.h" />
<ClInclude Include="src\cubeb_mixer.h" />
<ClInclude Include="src\cubeb_resampler.h" />
<ClInclude Include="src\cubeb_resampler_internal.h" />
<ClInclude Include="src\cubeb_ring_array.h" />
<ClInclude Include="src\cubeb_ringbuffer.h" />
<ClInclude Include="src\cubeb_strings.h" />
<ClInclude Include="src\cubeb_utils.h" />
<ClInclude Include="src\cubeb_utils_win.h" />
<ClInclude Include="subprojects\speex\fixed_generic.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\subprojects\speex\resample_neon.h">
<ClInclude Include="subprojects\speex\resample_neon.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\subprojects\speex\resample_sse.h">
<ClInclude Include="subprojects\speex\resample_sse.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\subprojects\speex\speex_config_types.h">
<ClInclude Include="subprojects\speex\speex_config_types.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\subprojects\speex\speex_resampler.h">
<ClInclude Include="subprojects\speex\speex_resampler.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\subprojects\speex\stack_alloc.h">
<ClInclude Include="subprojects\speex\stack_alloc.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\subprojects\speex\arch.h">
<ClInclude Include="subprojects\speex\arch.h">
<Filter>speex</Filter>
</ClInclude>
<ClInclude Include="cubeb\include\cubeb\cubeb.h" />
<ClInclude Include="include\cubeb\cubeb.h" />
<ClInclude Include="include\cubeb_export.h" />
</ItemGroup>
<ItemGroup>
@@ -44,15 +44,15 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cubeb\src\cubeb_wasapi.cpp" />
<ClCompile Include="cubeb\src\cubeb_winmm.c" />
<ClCompile Include="cubeb\src\cubeb.c" />
<ClCompile Include="cubeb\src\cubeb_log.cpp" />
<ClCompile Include="cubeb\src\cubeb_mixer.cpp" />
<ClCompile Include="cubeb\src\cubeb_resampler.cpp" />
<ClCompile Include="cubeb\src\cubeb_strings.c" />
<ClCompile Include="cubeb\src\cubeb_utils.cpp" />
<ClCompile Include="cubeb\subprojects\speex\resample.c">
<ClCompile Include="src\cubeb_wasapi.cpp" />
<ClCompile Include="src\cubeb_winmm.c" />
<ClCompile Include="src\cubeb.c" />
<ClCompile Include="src\cubeb_log.cpp" />
<ClCompile Include="src\cubeb_mixer.cpp" />
<ClCompile Include="src\cubeb_resampler.cpp" />
<ClCompile Include="src\cubeb_strings.c" />
<ClCompile Include="src\cubeb_utils.cpp" />
<ClCompile Include="subprojects\speex\resample.c">
<Filter>speex</Filter>
</ClCompile>
</ItemGroup>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
+730
View File
@@ -0,0 +1,730 @@
/*
* Copyright © 2011 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382)
#define CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382
#include "cubeb_export.h"
#include <stdint.h>
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
/** @mainpage
@section intro Introduction
This is the documentation for the <tt>libcubeb</tt> C API.
<tt>libcubeb</tt> is a callback-based audio API library allowing the
authoring of portable multiplatform audio playback and recording.
@section example Example code
This example shows how to create a duplex stream that pipes the microphone
to the speakers, with minimal latency and the proper sample-rate for the
platform.
@code
cubeb * app_ctx;
cubeb_init(&app_ctx, "Example Application", NULL);
int rv;
uint32_t rate;
uint32_t latency_frames;
uint64_t ts;
rv = cubeb_get_preferred_sample_rate(app_ctx, &rate);
if (rv != CUBEB_OK) {
fprintf(stderr, "Could not get preferred sample-rate");
return rv;
}
cubeb_stream_params output_params;
output_params.format = CUBEB_SAMPLE_FLOAT32NE;
output_params.rate = rate;
output_params.channels = 2;
output_params.layout = CUBEB_LAYOUT_UNDEFINED;
output_params.prefs = CUBEB_STREAM_PREF_NONE;
rv = cubeb_get_min_latency(app_ctx, &output_params, &latency_frames);
if (rv != CUBEB_OK) {
fprintf(stderr, "Could not get minimum latency");
return rv;
}
cubeb_stream_params input_params;
input_params.format = CUBEB_SAMPLE_FLOAT32NE;
input_params.rate = rate;
input_params.channels = 1;
input_params.layout = CUBEB_LAYOUT_UNDEFINED;
input_params.prefs = CUBEB_STREAM_PREF_NONE;
cubeb_stream * stm;
rv = cubeb_stream_init(app_ctx, &stm, "Example Stream 1",
NULL, &input_params,
NULL, &output_params,
latency_frames,
data_cb, state_cb,
NULL);
if (rv != CUBEB_OK) {
fprintf(stderr, "Could not open the stream");
return rv;
}
rv = cubeb_stream_start(stm);
if (rv != CUBEB_OK) {
fprintf(stderr, "Could not start the stream");
return rv;
}
for (;;) {
cubeb_stream_get_position(stm, &ts);
printf("time=%llu\n", ts);
sleep(1);
}
rv = cubeb_stream_stop(stm);
if (rv != CUBEB_OK) {
fprintf(stderr, "Could not stop the stream");
return rv;
}
cubeb_stream_destroy(stm);
cubeb_destroy(app_ctx);
@endcode
@code
long data_cb(cubeb_stream * stm, void * user,
const void * input_buffer, void * output_buffer, long nframes)
{
const float * in = input_buffer;
float * out = output_buffer;
for (int i = 0; i < nframes; ++i) {
for (int c = 0; c < 2; ++c) {
out[2 * i + c] = in[i];
}
}
return nframes;
}
@endcode
@code
void state_cb(cubeb_stream * stm, void * user, cubeb_state state)
{
printf("state=%d\n", state);
}
@endcode
*/
/** @file
The <tt>libcubeb</tt> C API. */
typedef struct cubeb
cubeb; /**< Opaque handle referencing the application state. */
typedef struct cubeb_stream
cubeb_stream; /**< Opaque handle referencing the stream state. */
/** Sample format enumeration. */
typedef enum {
/**< Little endian 16-bit signed PCM. */
CUBEB_SAMPLE_S16LE,
/**< Big endian 16-bit signed PCM. */
CUBEB_SAMPLE_S16BE,
/**< Little endian 32-bit IEEE floating point PCM. */
CUBEB_SAMPLE_FLOAT32LE,
/**< Big endian 32-bit IEEE floating point PCM. */
CUBEB_SAMPLE_FLOAT32BE,
#if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__)
/**< Native endian 16-bit signed PCM. */
CUBEB_SAMPLE_S16NE = CUBEB_SAMPLE_S16BE,
/**< Native endian 32-bit IEEE floating point PCM. */
CUBEB_SAMPLE_FLOAT32NE = CUBEB_SAMPLE_FLOAT32BE
#else
/**< Native endian 16-bit signed PCM. */
CUBEB_SAMPLE_S16NE = CUBEB_SAMPLE_S16LE,
/**< Native endian 32-bit IEEE floating point PCM. */
CUBEB_SAMPLE_FLOAT32NE = CUBEB_SAMPLE_FLOAT32LE
#endif
} cubeb_sample_format;
/** An opaque handle used to refer a particular input or output device
* across calls. */
typedef void const * cubeb_devid;
/** Level (verbosity) of logging for a particular cubeb context. */
typedef enum {
CUBEB_LOG_DISABLED = 0, /** < Logging disabled */
CUBEB_LOG_NORMAL =
1, /**< Logging lifetime operation (creation/destruction). */
CUBEB_LOG_VERBOSE = 2, /**< Verbose logging of callbacks, can have performance
implications. */
} cubeb_log_level;
typedef enum {
CHANNEL_UNKNOWN = 0,
CHANNEL_FRONT_LEFT = 1 << 0,
CHANNEL_FRONT_RIGHT = 1 << 1,
CHANNEL_FRONT_CENTER = 1 << 2,
CHANNEL_LOW_FREQUENCY = 1 << 3,
CHANNEL_BACK_LEFT = 1 << 4,
CHANNEL_BACK_RIGHT = 1 << 5,
CHANNEL_FRONT_LEFT_OF_CENTER = 1 << 6,
CHANNEL_FRONT_RIGHT_OF_CENTER = 1 << 7,
CHANNEL_BACK_CENTER = 1 << 8,
CHANNEL_SIDE_LEFT = 1 << 9,
CHANNEL_SIDE_RIGHT = 1 << 10,
CHANNEL_TOP_CENTER = 1 << 11,
CHANNEL_TOP_FRONT_LEFT = 1 << 12,
CHANNEL_TOP_FRONT_CENTER = 1 << 13,
CHANNEL_TOP_FRONT_RIGHT = 1 << 14,
CHANNEL_TOP_BACK_LEFT = 1 << 15,
CHANNEL_TOP_BACK_CENTER = 1 << 16,
CHANNEL_TOP_BACK_RIGHT = 1 << 17
} cubeb_channel;
typedef uint32_t cubeb_channel_layout;
// Some common layout definitions.
enum {
CUBEB_LAYOUT_UNDEFINED = 0, // Indicate the speaker's layout is undefined.
CUBEB_LAYOUT_MONO = CHANNEL_FRONT_CENTER,
CUBEB_LAYOUT_MONO_LFE = CUBEB_LAYOUT_MONO | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_STEREO = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT,
CUBEB_LAYOUT_STEREO_LFE = CUBEB_LAYOUT_STEREO | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_3F =
CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER,
CUBEB_LAYOUT_3F_LFE = CUBEB_LAYOUT_3F | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_2F1 =
CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_BACK_CENTER,
CUBEB_LAYOUT_2F1_LFE = CUBEB_LAYOUT_2F1 | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_3F1 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER,
CUBEB_LAYOUT_3F1_LFE = CUBEB_LAYOUT_3F1 | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_2F2 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
CUBEB_LAYOUT_2F2_LFE = CUBEB_LAYOUT_2F2 | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_QUAD = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT,
CUBEB_LAYOUT_QUAD_LFE = CUBEB_LAYOUT_QUAD | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_3F2 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
CHANNEL_FRONT_CENTER | CHANNEL_SIDE_LEFT |
CHANNEL_SIDE_RIGHT,
CUBEB_LAYOUT_3F2_LFE = CUBEB_LAYOUT_3F2 | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_3F2_BACK = CUBEB_LAYOUT_QUAD | CHANNEL_FRONT_CENTER,
CUBEB_LAYOUT_3F2_LFE_BACK = CUBEB_LAYOUT_3F2_BACK | CHANNEL_LOW_FREQUENCY,
CUBEB_LAYOUT_3F3R_LFE = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
CHANNEL_BACK_CENTER | CHANNEL_SIDE_LEFT |
CHANNEL_SIDE_RIGHT,
CUBEB_LAYOUT_3F4_LFE = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
};
/** Miscellaneous stream preferences. */
typedef enum {
CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */
CUBEB_STREAM_PREF_LOOPBACK =
0x01, /**< Request a loopback stream. Should be
specified on the input params and an
output device to loopback from should
be passed in place of an input device. */
CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
default device on OS
changes. */
CUBEB_STREAM_PREF_VOICE =
0x04, /**< This stream is going to transport voice data.
Depending on the backend and platform, this can
change the audio input or output devices
selected, as well as the quality of the stream,
for example to accomodate bluetooth SCO modes on
bluetooth devices. */
CUBEB_STREAM_PREF_RAW =
0x08, /**< Windows only. Bypass all signal processing
except for always on APO, driver and hardware. */
CUBEB_STREAM_PREF_PERSIST = 0x10, /**< Request that the volume and mute
settings should persist across restarts
of the stream and/or application. This is
obsolete and ignored by all backends. */
CUBEB_STREAM_PREF_JACK_NO_AUTO_CONNECT = 0x20 /**< Don't automatically try to
connect ports. Only affects
the jack backend. */
} cubeb_stream_prefs;
/** Stream format initialization parameters. */
typedef struct {
cubeb_sample_format format; /**< Requested sample format. One of
#cubeb_sample_format. */
uint32_t rate; /**< Requested sample rate. Valid range is [1000, 192000]. */
uint32_t channels; /**< Requested channel count. Valid range is [1, 8]. */
cubeb_channel_layout
layout; /**< Requested channel layout. This must be consistent with the
provided channels. CUBEB_LAYOUT_UNDEFINED if unknown */
cubeb_stream_prefs prefs; /**< Requested preferences. */
} cubeb_stream_params;
/** Audio device description */
typedef struct {
char * output_name; /**< The name of the output device */
char * input_name; /**< The name of the input device */
} cubeb_device;
/** Stream states signaled via state_callback. */
typedef enum {
CUBEB_STATE_STARTED, /**< Stream started. */
CUBEB_STATE_STOPPED, /**< Stream stopped. */
CUBEB_STATE_DRAINED, /**< Stream drained. */
CUBEB_STATE_ERROR /**< Stream disabled due to error. */
} cubeb_state;
/** Result code enumeration. */
enum {
CUBEB_OK = 0, /**< Success. */
CUBEB_ERROR = -1, /**< Unclassified error. */
CUBEB_ERROR_INVALID_FORMAT =
-2, /**< Unsupported #cubeb_stream_params requested. */
CUBEB_ERROR_INVALID_PARAMETER = -3, /**< Invalid parameter specified. */
CUBEB_ERROR_NOT_SUPPORTED =
-4, /**< Optional function not implemented in current backend. */
CUBEB_ERROR_DEVICE_UNAVAILABLE =
-5 /**< Device specified by #cubeb_devid not available. */
};
/**
* Whether a particular device is an input device (e.g. a microphone), or an
* output device (e.g. headphones). */
typedef enum {
CUBEB_DEVICE_TYPE_UNKNOWN,
CUBEB_DEVICE_TYPE_INPUT,
CUBEB_DEVICE_TYPE_OUTPUT
} cubeb_device_type;
/**
* The state of a device.
*/
typedef enum {
CUBEB_DEVICE_STATE_DISABLED, /**< The device has been disabled at the system
level. */
CUBEB_DEVICE_STATE_UNPLUGGED, /**< The device is enabled, but nothing is
plugged into it. */
CUBEB_DEVICE_STATE_ENABLED /**< The device is enabled. */
} cubeb_device_state;
/**
* Architecture specific sample type.
*/
typedef enum {
CUBEB_DEVICE_FMT_S16LE = 0x0010, /**< 16-bit integers, Little Endian. */
CUBEB_DEVICE_FMT_S16BE = 0x0020, /**< 16-bit integers, Big Endian. */
CUBEB_DEVICE_FMT_F32LE = 0x1000, /**< 32-bit floating point, Little Endian. */
CUBEB_DEVICE_FMT_F32BE = 0x2000 /**< 32-bit floating point, Big Endian. */
} cubeb_device_fmt;
#if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__)
/** 16-bit integers, native endianess, when on a Big Endian environment. */
#define CUBEB_DEVICE_FMT_S16NE CUBEB_DEVICE_FMT_S16BE
/** 32-bit floating points, native endianess, when on a Big Endian environment.
*/
#define CUBEB_DEVICE_FMT_F32NE CUBEB_DEVICE_FMT_F32BE
#else
/** 16-bit integers, native endianess, when on a Little Endian environment. */
#define CUBEB_DEVICE_FMT_S16NE CUBEB_DEVICE_FMT_S16LE
/** 32-bit floating points, native endianess, when on a Little Endian
* environment. */
#define CUBEB_DEVICE_FMT_F32NE CUBEB_DEVICE_FMT_F32LE
#endif
/** All the 16-bit integers types. */
#define CUBEB_DEVICE_FMT_S16_MASK \
(CUBEB_DEVICE_FMT_S16LE | CUBEB_DEVICE_FMT_S16BE)
/** All the 32-bit floating points types. */
#define CUBEB_DEVICE_FMT_F32_MASK \
(CUBEB_DEVICE_FMT_F32LE | CUBEB_DEVICE_FMT_F32BE)
/** All the device formats types. */
#define CUBEB_DEVICE_FMT_ALL \
(CUBEB_DEVICE_FMT_S16_MASK | CUBEB_DEVICE_FMT_F32_MASK)
/** Channel type for a `cubeb_stream`. Depending on the backend and platform
* used, this can control inter-stream interruption, ducking, and volume
* control.
*/
typedef enum {
CUBEB_DEVICE_PREF_NONE = 0x00,
CUBEB_DEVICE_PREF_MULTIMEDIA = 0x01,
CUBEB_DEVICE_PREF_VOICE = 0x02,
CUBEB_DEVICE_PREF_NOTIFICATION = 0x04,
CUBEB_DEVICE_PREF_ALL = 0x0F
} cubeb_device_pref;
/** This structure holds the characteristics
* of an input or output audio device. It is obtained using
* `cubeb_enumerate_devices`, which returns these structures via
* `cubeb_device_collection` and must be destroyed via
* `cubeb_device_collection_destroy`. */
typedef struct {
cubeb_devid devid; /**< Device identifier handle. */
char const *
device_id; /**< Device identifier which might be presented in a UI. */
char const * friendly_name; /**< Friendly device name which might be presented
in a UI. */
char const * group_id; /**< Two devices have the same group identifier if they
belong to the same physical device; for example a
headset and microphone. */
char const * vendor_name; /**< Optional vendor name, may be NULL. */
cubeb_device_type type; /**< Type of device (Input/Output). */
cubeb_device_state state; /**< State of device disabled/enabled/unplugged. */
cubeb_device_pref preferred; /**< Preferred device. */
cubeb_device_fmt format; /**< Sample format supported. */
cubeb_device_fmt
default_format; /**< The default sample format for this device. */
uint32_t max_channels; /**< Channels. */
uint32_t default_rate; /**< Default/Preferred sample rate. */
uint32_t max_rate; /**< Maximum sample rate supported. */
uint32_t min_rate; /**< Minimum sample rate supported. */
uint32_t latency_lo; /**< Lowest possible latency in frames. */
uint32_t latency_hi; /**< Higest possible latency in frames. */
} cubeb_device_info;
/** Device collection.
* Returned by `cubeb_enumerate_devices` and destroyed by
* `cubeb_device_collection_destroy`. */
typedef struct {
cubeb_device_info * device; /**< Array of pointers to device info. */
size_t count; /**< Device count in collection. */
} cubeb_device_collection;
/** User supplied data callback.
- Calling other cubeb functions from this callback is unsafe.
- The code in the callback should be non-blocking.
- Returning less than the number of frames this callback asks for or
provides puts the stream in drain mode. This callback will not be called
again, and the state callback will be called with CUBEB_STATE_DRAINED when
all the frames have been output.
@param stream The stream for which this callback fired.
@param user_ptr The pointer passed to cubeb_stream_init.
@param input_buffer A pointer containing the input data, or nullptr
if this is an output-only stream.
@param output_buffer A pointer to a buffer to be filled with audio samples,
or nullptr if this is an input-only stream.
@param nframes The number of frames of the two buffer.
@retval If the stream has output, this is the number of frames written to
the output buffer. In this case, if this number is less than
nframes then the stream will start to drain. If the stream is
input only, then returning nframes indicates data has been read.
In this case, a value less than nframes will result in the stream
being stopped.
@retval CUBEB_ERROR on error, in which case the data callback will stop
and the stream will enter a shutdown state. */
typedef long (*cubeb_data_callback)(cubeb_stream * stream, void * user_ptr,
void const * input_buffer,
void * output_buffer, long nframes);
/** User supplied state callback.
@param stream The stream for this this callback fired.
@param user_ptr The pointer passed to cubeb_stream_init.
@param state The new state of the stream. */
typedef void (*cubeb_state_callback)(cubeb_stream * stream, void * user_ptr,
cubeb_state state);
/**
* User supplied callback called when the underlying device changed.
* @param user The pointer passed to cubeb_stream_init. */
typedef void (*cubeb_device_changed_callback)(void * user_ptr);
/**
* User supplied callback called when the underlying device collection changed.
* @param context A pointer to the cubeb context.
* @param user_ptr The pointer passed to
* cubeb_register_device_collection_changed. */
typedef void (*cubeb_device_collection_changed_callback)(cubeb * context,
void * user_ptr);
/** User supplied callback called when a message needs logging. */
typedef void (*cubeb_log_callback)(char const * fmt, ...);
/** Initialize an application context. This will perform any library or
application scoped initialization.
Note: On Windows platforms, COM must be initialized in MTA mode on
any thread that will call the cubeb API.
@param context A out param where an opaque pointer to the application
context will be returned.
@param context_name A name for the context. Depending on the platform this
can appear in different locations.
@param backend_name The name of the cubeb backend user desires to select.
Accepted values self-documented in cubeb.c: init_oneshot
If NULL, a default ordering is used for backend choice.
A valid choice overrides all other possible backends,
so long as the backend was included at compile time.
@retval CUBEB_OK in case of success.
@retval CUBEB_ERROR in case of error, for example because the host
has no audio hardware. */
CUBEB_EXPORT int
cubeb_init(cubeb ** context, char const * context_name,
char const * backend_name);
/** Returns a list of backend names which can be supplid to cubeb_init().
Array is null-terminated. */
CUBEB_EXPORT const char* const*
cubeb_get_backend_names();
/** Get a read-only string identifying this context's current backend.
@param context A pointer to the cubeb context.
@retval Read-only string identifying current backend. */
CUBEB_EXPORT char const *
cubeb_get_backend_id(cubeb * context);
/** Get the maximum possible number of channels.
@param context A pointer to the cubeb context.
@param max_channels The maximum number of channels.
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER
@retval CUBEB_ERROR_NOT_SUPPORTED
@retval CUBEB_ERROR */
CUBEB_EXPORT int
cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels);
/** Get the minimal latency value, in frames, that is guaranteed to work
when creating a stream for the specified sample rate. This is platform,
hardware and backend dependent.
@param context A pointer to the cubeb context.
@param params On some backends, the minimum achievable latency depends on
the characteristics of the stream.
@param latency_frames The latency value, in frames, to pass to
cubeb_stream_init.
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_get_min_latency(cubeb * context, cubeb_stream_params * params,
uint32_t * latency_frames);
/** Get the preferred sample rate for this backend: this is hardware and
platform dependent, and can avoid resampling, and/or trigger fastpaths.
@param context A pointer to the cubeb context.
@param rate The samplerate (in Hz) the current configuration prefers.
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate);
/** Destroy an application context. This must be called after all stream have
* been destroyed.
@param context A pointer to the cubeb context.*/
CUBEB_EXPORT void
cubeb_destroy(cubeb * context);
/** Initialize a stream associated with the supplied application context.
@param context A pointer to the cubeb context.
@param stream An out parameter to be filled with the an opaque pointer to a
cubeb stream.
@param stream_name A name for this stream.
@param input_device Device for the input side of the stream. If NULL the
default input device is used. Passing a valid
cubeb_devid means the stream only ever uses that device. Passing a NULL
cubeb_devid allows the stream to follow that device
type's OS default.
@param input_stream_params Parameters for the input side of the stream, or
NULL if this stream is output only.
@param output_device Device for the output side of the stream. If NULL the
default output device is used. Passing a valid
cubeb_devid means the stream only ever uses that device. Passing a NULL
cubeb_devid allows the stream to follow that device
type's OS default.
@param output_stream_params Parameters for the output side of the stream, or
NULL if this stream is input only. When input
and output stream parameters are supplied, their
rate has to be the same.
@param latency_frames Stream latency in frames. Valid range
is [1, 96000].
@param data_callback Will be called to preroll data before playback is
started by cubeb_stream_start.
@param state_callback A pointer to a state callback.
@param user_ptr A pointer that will be passed to the callbacks. This pointer
must outlive the life time of the stream.
@retval CUBEB_OK
@retval CUBEB_ERROR
@retval CUBEB_ERROR_INVALID_FORMAT
@retval CUBEB_ERROR_DEVICE_UNAVAILABLE */
CUBEB_EXPORT int
cubeb_stream_init(cubeb * context, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
uint32_t latency_frames, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr);
/** Destroy a stream. `cubeb_stream_stop` MUST be called before destroying a
stream.
@param stream The stream to destroy. */
CUBEB_EXPORT void
cubeb_stream_destroy(cubeb_stream * stream);
/** Start playback.
@param stream
@retval CUBEB_OK
@retval CUBEB_ERROR */
CUBEB_EXPORT int
cubeb_stream_start(cubeb_stream * stream);
/** Stop playback.
@param stream
@retval CUBEB_OK
@retval CUBEB_ERROR */
CUBEB_EXPORT int
cubeb_stream_stop(cubeb_stream * stream);
/** Get the current stream playback position.
@param stream
@param position Playback position in frames.
@retval CUBEB_OK
@retval CUBEB_ERROR */
CUBEB_EXPORT int
cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position);
/** Get the latency for this stream, in frames. This is the number of frames
between the time cubeb acquires the data in the callback and the listener
can hear the sound.
@param stream
@param latency Current approximate stream latency in frames.
@retval CUBEB_OK
@retval CUBEB_ERROR_NOT_SUPPORTED
@retval CUBEB_ERROR */
CUBEB_EXPORT int
cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency);
/** Get the input latency for this stream, in frames. This is the number of
frames between the time the audio input devices records the data, and they
are available in the data callback.
This returns CUBEB_ERROR when the stream is output-only.
@param stream
@param latency Current approximate stream latency in frames.
@retval CUBEB_OK
@retval CUBEB_ERROR_NOT_SUPPORTED
@retval CUBEB_ERROR */
CUBEB_EXPORT int
cubeb_stream_get_input_latency(cubeb_stream * stream, uint32_t * latency);
/** Set the volume for a stream.
@param stream the stream for which to adjust the volume.
@param volume a float between 0.0 (muted) and 1.0 (maximum volume)
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER volume is outside [0.0, 1.0] or
stream is an invalid pointer
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_stream_set_volume(cubeb_stream * stream, float volume);
/** Change a stream's name.
@param stream the stream for which to set the name.
@param stream_name the new name for the stream
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER if any pointer is invalid
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_stream_set_name(cubeb_stream * stream, char const * stream_name);
/** Get the current output device for this stream.
@param stm the stream for which to query the current output device
@param device a pointer in which the current output device will be stored.
@retval CUBEB_OK in case of success
@retval CUBEB_ERROR_INVALID_PARAMETER if either stm, device or count are
invalid pointers
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_stream_get_current_device(cubeb_stream * stm,
cubeb_device ** const device);
/** Destroy a cubeb_device structure.
@param stream the stream passed in cubeb_stream_get_current_device
@param devices the devices to destroy
@retval CUBEB_OK in case of success
@retval CUBEB_ERROR_INVALID_PARAMETER if devices is an invalid pointer
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_stream_device_destroy(cubeb_stream * stream, cubeb_device * devices);
/** Set a callback to be notified when the output device changes.
@param stream the stream for which to set the callback.
@param device_changed_callback a function called whenever the device has
changed. Passing NULL allow to unregister a function
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER if either stream or
device_changed_callback are invalid pointers.
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_stream_register_device_changed_callback(
cubeb_stream * stream,
cubeb_device_changed_callback device_changed_callback);
/** Return the user data pointer registered with the stream with
cubeb_stream_init.
@param stream the stream for which to retrieve user data pointer.
@retval user data pointer */
CUBEB_EXPORT void *
cubeb_stream_user_ptr(cubeb_stream * stream);
/** Returns enumerated devices.
@param context
@param devtype device type to include
@param collection output collection. Must be destroyed with
cubeb_device_collection_destroy
@retval CUBEB_OK in case of success
@retval CUBEB_ERROR_INVALID_PARAMETER if collection is an invalid pointer
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_enumerate_devices(cubeb * context, cubeb_device_type devtype,
cubeb_device_collection * collection);
/** Destroy a cubeb_device_collection, and its `cubeb_device_info`.
@param context
@param collection collection to destroy
@retval CUBEB_OK
@retval CUBEB_ERROR_INVALID_PARAMETER if collection is an invalid pointer */
CUBEB_EXPORT int
cubeb_device_collection_destroy(cubeb * context,
cubeb_device_collection * collection);
/** Registers a callback which is called when the system detects
a new device or a device is removed.
@param context
@param devtype device type to include. Different callbacks and user pointers
can be registered for each devtype. The hybrid devtype
`CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT` is also valid
and will register the provided callback and user pointer in both
sides.
@param callback a function called whenever the system device list changes.
Passing NULL allow to unregister a function. You have to unregister
first before you register a new callback.
@param user_ptr pointer to user specified data which will be present in
subsequent callbacks.
@retval CUBEB_ERROR_NOT_SUPPORTED */
CUBEB_EXPORT int
cubeb_register_device_collection_changed(
cubeb * context, cubeb_device_type devtype,
cubeb_device_collection_changed_callback callback, void * user_ptr);
/** Set a callback to be called with a message.
@param log_level CUBEB_LOG_VERBOSE, CUBEB_LOG_NORMAL.
@param log_callback A function called with a message when there is
something to log. Pass NULL to unregister.
@retval CUBEB_OK in case of success.
@retval CUBEB_ERROR_INVALID_PARAMETER if either context or log_callback are
invalid pointers, or if level is not
in cubeb_log_level. */
CUBEB_EXPORT int
cubeb_set_log_callback(cubeb_log_level log_level,
cubeb_log_callback log_callback);
#if defined(__cplusplus)
}
#endif
#endif /* CUBEB_c2f983e9_c96f_e71c_72c3_bbf62992a382 */
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
/*
* The following definitions are copied from the android sources. Only the
* relevant enum member and values needed are copied.
*/
/*
* From
* https://android.googlesource.com/platform/frameworks/base/+/android-2.2.3_r2.1/include/utils/Errors.h
*/
typedef int32_t status_t;
/*
* From
* https://android.googlesource.com/platform/frameworks/base/+/android-2.2.3_r2.1/include/media/AudioTrack.h
*/
struct Buffer {
uint32_t flags;
int channelCount;
int format;
size_t frameCount;
size_t size;
union {
void * raw;
short * i16;
int8_t * i8;
};
};
enum event_type {
EVENT_MORE_DATA = 0,
EVENT_UNDERRUN = 1,
EVENT_LOOP_END = 2,
EVENT_MARKER = 3,
EVENT_NEW_POS = 4,
EVENT_BUFFER_END = 5
};
/**
* From
* https://android.googlesource.com/platform/frameworks/base/+/android-2.2.3_r2.1/include/media/AudioSystem.h
* and
* https://android.googlesource.com/platform/system/core/+/android-4.2.2_r1/include/system/audio.h
*/
#define AUDIO_STREAM_TYPE_MUSIC 3
enum {
AUDIO_CHANNEL_OUT_FRONT_LEFT_ICS = 0x1,
AUDIO_CHANNEL_OUT_FRONT_RIGHT_ICS = 0x2,
AUDIO_CHANNEL_OUT_MONO_ICS = AUDIO_CHANNEL_OUT_FRONT_LEFT_ICS,
AUDIO_CHANNEL_OUT_STEREO_ICS =
(AUDIO_CHANNEL_OUT_FRONT_LEFT_ICS | AUDIO_CHANNEL_OUT_FRONT_RIGHT_ICS)
} AudioTrack_ChannelMapping_ICS;
enum {
AUDIO_CHANNEL_OUT_FRONT_LEFT_Legacy = 0x4,
AUDIO_CHANNEL_OUT_FRONT_RIGHT_Legacy = 0x8,
AUDIO_CHANNEL_OUT_MONO_Legacy = AUDIO_CHANNEL_OUT_FRONT_LEFT_Legacy,
AUDIO_CHANNEL_OUT_STEREO_Legacy = (AUDIO_CHANNEL_OUT_FRONT_LEFT_Legacy |
AUDIO_CHANNEL_OUT_FRONT_RIGHT_Legacy)
} AudioTrack_ChannelMapping_Legacy;
typedef enum {
AUDIO_FORMAT_PCM = 0x00000000,
AUDIO_FORMAT_PCM_SUB_16_BIT = 0x1,
AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_16_BIT),
} AudioTrack_SampleType;
+76
View File
@@ -0,0 +1,76 @@
#ifndef _CUBEB_OUTPUT_LATENCY_H_
#define _CUBEB_OUTPUT_LATENCY_H_
#include "../cubeb-jni.h"
#include "cubeb_media_library.h"
#include <stdbool.h>
struct output_latency_function {
media_lib * from_lib;
cubeb_jni * from_jni;
int version;
};
typedef struct output_latency_function output_latency_function;
const int ANDROID_JELLY_BEAN_MR1_4_2 = 17;
output_latency_function *
cubeb_output_latency_load_method(int version)
{
output_latency_function * ol = NULL;
ol = calloc(1, sizeof(output_latency_function));
ol->version = version;
if (ol->version > ANDROID_JELLY_BEAN_MR1_4_2) {
ol->from_jni = cubeb_jni_init();
return ol;
}
ol->from_lib = cubeb_load_media_library();
return ol;
}
bool
cubeb_output_latency_method_is_loaded(output_latency_function * ol)
{
assert(ol);
if (ol->version > ANDROID_JELLY_BEAN_MR1_4_2) {
return !!ol->from_jni;
}
return !!ol->from_lib;
}
void
cubeb_output_latency_unload_method(output_latency_function * ol)
{
if (!ol) {
return;
}
if (ol->version > ANDROID_JELLY_BEAN_MR1_4_2 && ol->from_jni) {
cubeb_jni_destroy(ol->from_jni);
}
if (ol->version <= ANDROID_JELLY_BEAN_MR1_4_2 && ol->from_lib) {
cubeb_close_media_library(ol->from_lib);
}
free(ol);
}
uint32_t
cubeb_get_output_latency(output_latency_function * ol)
{
assert(cubeb_output_latency_method_is_loaded(ol));
if (ol->version > ANDROID_JELLY_BEAN_MR1_4_2) {
return cubeb_get_output_latency_from_jni(ol->from_jni);
}
return cubeb_get_output_latency_from_media_library(ol->from_lib);
}
#endif // _CUBEB_OUTPUT_LATENCY_H_
+64
View File
@@ -0,0 +1,64 @@
#ifndef _CUBEB_MEDIA_LIBRARY_H_
#define _CUBEB_MEDIA_LIBRARY_H_
struct media_lib {
void * libmedia;
int32_t (*get_output_latency)(uint32_t * latency, int stream_type);
};
typedef struct media_lib media_lib;
media_lib *
cubeb_load_media_library()
{
media_lib ml = {0};
ml.libmedia = dlopen("libmedia.so", RTLD_LAZY);
if (!ml.libmedia) {
return NULL;
}
// Get the latency, in ms, from AudioFlinger. First, try the most recent
// signature. status_t AudioSystem::getOutputLatency(uint32_t* latency,
// audio_stream_type_t streamType)
ml.get_output_latency = dlsym(
ml.libmedia,
"_ZN7android11AudioSystem16getOutputLatencyEPj19audio_stream_type_t");
if (!ml.get_output_latency) {
// In case of failure, try the signature from legacy version.
// status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType)
ml.get_output_latency =
dlsym(ml.libmedia, "_ZN7android11AudioSystem16getOutputLatencyEPji");
if (!ml.get_output_latency) {
return NULL;
}
}
media_lib * rv = NULL;
rv = calloc(1, sizeof(media_lib));
assert(rv);
*rv = ml;
return rv;
}
void
cubeb_close_media_library(media_lib * ml)
{
dlclose(ml->libmedia);
ml->libmedia = NULL;
ml->get_output_latency = NULL;
free(ml);
}
uint32_t
cubeb_get_output_latency_from_media_library(media_lib * ml)
{
uint32_t latency = 0;
const int audio_stream_type_music = 3;
int32_t r = ml->get_output_latency(&latency, audio_stream_type_music);
if (r) {
return 0;
}
return latency;
}
#endif // _CUBEB_MEDIA_LIBRARY_H_
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This file is similar to the file "OpenSLES_AndroidConfiguration.h" found in
* the Android NDK, but removes the #ifdef __cplusplus defines, so we can keep
* using a C compiler in cubeb.
*/
#ifndef OPENSL_ES_ANDROIDCONFIGURATION_H_
#define OPENSL_ES_ANDROIDCONFIGURATION_H_
/*---------------------------------------------------------------------------*/
/* Android AudioRecorder configuration */
/*---------------------------------------------------------------------------*/
/** Audio recording preset */
/** Audio recording preset key */
#define SL_ANDROID_KEY_RECORDING_PRESET \
((const SLchar *)"androidRecordingPreset")
/** Audio recording preset values */
/** preset "none" cannot be set, it is used to indicate the current settings
* do not match any of the presets. */
#define SL_ANDROID_RECORDING_PRESET_NONE ((SLuint32)0x00000000)
/** generic recording configuration on the platform */
#define SL_ANDROID_RECORDING_PRESET_GENERIC ((SLuint32)0x00000001)
/** uses the microphone audio source with the same orientation as the camera
* if available, the main device microphone otherwise */
#define SL_ANDROID_RECORDING_PRESET_CAMCORDER ((SLuint32)0x00000002)
/** uses the main microphone tuned for voice recognition */
#define SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION ((SLuint32)0x00000003)
/** uses the main microphone tuned for audio communications */
#define SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION ((SLuint32)0x00000004)
/** uses the main microphone unprocessed */
#define SL_ANDROID_RECORDING_PRESET_UNPROCESSED ((SLuint32)0x00000005)
/*---------------------------------------------------------------------------*/
/* Android AudioPlayer configuration */
/*---------------------------------------------------------------------------*/
/** Audio playback stream type */
/** Audio playback stream type key */
#define SL_ANDROID_KEY_STREAM_TYPE ((const SLchar *)"androidPlaybackStreamType")
/** Audio playback stream type values */
/* same as android.media.AudioManager.STREAM_VOICE_CALL */
#define SL_ANDROID_STREAM_VOICE ((SLint32)0x00000000)
/* same as android.media.AudioManager.STREAM_SYSTEM */
#define SL_ANDROID_STREAM_SYSTEM ((SLint32)0x00000001)
/* same as android.media.AudioManager.STREAM_RING */
#define SL_ANDROID_STREAM_RING ((SLint32)0x00000002)
/* same as android.media.AudioManager.STREAM_MUSIC */
#define SL_ANDROID_STREAM_MEDIA ((SLint32)0x00000003)
/* same as android.media.AudioManager.STREAM_ALARM */
#define SL_ANDROID_STREAM_ALARM ((SLint32)0x00000004)
/* same as android.media.AudioManager.STREAM_NOTIFICATION */
#define SL_ANDROID_STREAM_NOTIFICATION ((SLint32)0x00000005)
/*---------------------------------------------------------------------------*/
/* Android AudioPlayer and AudioRecorder configuration */
/*---------------------------------------------------------------------------*/
/** Audio Performance mode.
* Performance mode tells the framework how to configure the audio path
* for a player or recorder according to application performance and
* functional requirements.
* It affects the output or input latency based on acceptable tradeoffs on
* battery drain and use of pre or post processing effects.
* Performance mode should be set before realizing the object and should be
* read after realizing the object to check if the requested mode could be
* granted or not.
*/
/** Audio Performance mode key */
#define SL_ANDROID_KEY_PERFORMANCE_MODE \
((const SLchar *)"androidPerformanceMode")
/** Audio performance values */
/* No specific performance requirement. Allows HW and SW pre/post
* processing. */
#define SL_ANDROID_PERFORMANCE_NONE ((SLuint32)0x00000000)
/* Priority given to latency. No HW or software pre/post processing.
* This is the default if no performance mode is specified. */
#define SL_ANDROID_PERFORMANCE_LATENCY ((SLuint32)0x00000001)
/* Priority given to latency while still allowing HW pre and post
* processing. */
#define SL_ANDROID_PERFORMANCE_LATENCY_EFFECTS ((SLuint32)0x00000002)
/* Priority given to power saving if latency is not a concern.
* Allows HW and SW pre/post processing. */
#define SL_ANDROID_PERFORMANCE_POWER_SAVING ((SLuint32)0x00000003)
#endif /* OPENSL_ES_ANDROIDCONFIGURATION_H_ */
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright © 2013 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5)
#define CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5
#include "cubeb/cubeb.h"
#include "cubeb_assert.h"
#include "cubeb_log.h"
#include <stdio.h>
#include <string.h>
#ifdef __clang__
#ifndef CLANG_ANALYZER_NORETURN
#if __has_feature(attribute_analyzer_noreturn)
#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
#else
#define CLANG_ANALYZER_NORETURN
#endif // ifndef CLANG_ANALYZER_NORETURN
#endif // __has_feature(attribute_analyzer_noreturn)
#else // __clang__
#define CLANG_ANALYZER_NORETURN
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
struct cubeb_ops {
int (*init)(cubeb ** context, char const * context_name);
char const * (*get_backend_id)(cubeb * context);
int (*get_max_channel_count)(cubeb * context, uint32_t * max_channels);
int (*get_min_latency)(cubeb * context, cubeb_stream_params params,
uint32_t * latency_ms);
int (*get_preferred_sample_rate)(cubeb * context, uint32_t * rate);
int (*enumerate_devices)(cubeb * context, cubeb_device_type type,
cubeb_device_collection * collection);
int (*device_collection_destroy)(cubeb * context,
cubeb_device_collection * collection);
void (*destroy)(cubeb * context);
int (*stream_init)(cubeb * context, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
unsigned int latency, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr);
void (*stream_destroy)(cubeb_stream * stream);
int (*stream_start)(cubeb_stream * stream);
int (*stream_stop)(cubeb_stream * stream);
int (*stream_get_position)(cubeb_stream * stream, uint64_t * position);
int (*stream_get_latency)(cubeb_stream * stream, uint32_t * latency);
int (*stream_get_input_latency)(cubeb_stream * stream, uint32_t * latency);
int (*stream_set_volume)(cubeb_stream * stream, float volumes);
int (*stream_set_name)(cubeb_stream * stream, char const * stream_name);
int (*stream_get_current_device)(cubeb_stream * stream,
cubeb_device ** const device);
int (*stream_device_destroy)(cubeb_stream * stream, cubeb_device * device);
int (*stream_register_device_changed_callback)(
cubeb_stream * stream,
cubeb_device_changed_callback device_changed_callback);
int (*register_device_collection_changed)(
cubeb * context, cubeb_device_type devtype,
cubeb_device_collection_changed_callback callback, void * user_ptr);
};
#endif /* CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5 */
+30
View File
@@ -0,0 +1,30 @@
#ifndef _CUBEB_JNI_INSTANCES_H_
#define _CUBEB_JNI_INSTANCES_H_
/*
* The methods in this file offer a way to pass in the required
* JNI instances in the cubeb library. By default they return NULL.
* In this case part of the cubeb API that depends on JNI
* will return CUBEB_ERROR_NOT_SUPPORTED. Currently only one
* method depends on that:
*
* cubeb_stream_get_position()
*
* Users that want to use that cubeb API method must "override"
* the methods bellow to return a valid instance of JavaVM
* and application's Context object.
* */
JNIEnv *
cubeb_get_jni_env_for_thread()
{
return nullptr;
}
jobject
cubeb_jni_get_context_instance()
{
return nullptr;
}
#endif //_CUBEB_JNI_INSTANCES_H_
+82
View File
@@ -0,0 +1,82 @@
/* clang-format off */
#include "jni.h"
#include <assert.h>
#include "cubeb-jni-instances.h"
/* clang-format on */
#define AUDIO_STREAM_TYPE_MUSIC 3
struct cubeb_jni {
jobject s_audio_manager_obj = nullptr;
jclass s_audio_manager_class = nullptr;
jmethodID s_get_output_latency_id = nullptr;
};
extern "C" cubeb_jni *
cubeb_jni_init()
{
jobject ctx_obj = cubeb_jni_get_context_instance();
JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
if (!jni_env || !ctx_obj) {
return nullptr;
}
cubeb_jni * cubeb_jni_ptr = new cubeb_jni;
assert(cubeb_jni_ptr);
// Find the audio manager object and make it global to call it from another
// method
jclass context_class = jni_env->FindClass("android/content/Context");
jfieldID audio_service_field = jni_env->GetStaticFieldID(
context_class, "AUDIO_SERVICE", "Ljava/lang/String;");
jstring jstr = (jstring)jni_env->GetStaticObjectField(context_class,
audio_service_field);
jmethodID get_system_service_id =
jni_env->GetMethodID(context_class, "getSystemService",
"(Ljava/lang/String;)Ljava/lang/Object;");
jobject audio_manager_obj =
jni_env->CallObjectMethod(ctx_obj, get_system_service_id, jstr);
cubeb_jni_ptr->s_audio_manager_obj =
reinterpret_cast<jobject>(jni_env->NewGlobalRef(audio_manager_obj));
// Make the audio manager class a global reference in order to preserve method
// id
jclass audio_manager_class = jni_env->FindClass("android/media/AudioManager");
cubeb_jni_ptr->s_audio_manager_class =
reinterpret_cast<jclass>(jni_env->NewGlobalRef(audio_manager_class));
cubeb_jni_ptr->s_get_output_latency_id =
jni_env->GetMethodID(audio_manager_class, "getOutputLatency", "(I)I");
jni_env->DeleteLocalRef(ctx_obj);
jni_env->DeleteLocalRef(context_class);
jni_env->DeleteLocalRef(jstr);
jni_env->DeleteLocalRef(audio_manager_obj);
jni_env->DeleteLocalRef(audio_manager_class);
return cubeb_jni_ptr;
}
extern "C" int
cubeb_get_output_latency_from_jni(cubeb_jni * cubeb_jni_ptr)
{
assert(cubeb_jni_ptr);
JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
return jni_env->CallIntMethod(
cubeb_jni_ptr->s_audio_manager_obj,
cubeb_jni_ptr->s_get_output_latency_id,
AUDIO_STREAM_TYPE_MUSIC); // param: AudioManager.STREAM_MUSIC
}
extern "C" void
cubeb_jni_destroy(cubeb_jni * cubeb_jni_ptr)
{
assert(cubeb_jni_ptr);
JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
assert(jni_env);
jni_env->DeleteGlobalRef(cubeb_jni_ptr->s_audio_manager_obj);
jni_env->DeleteGlobalRef(cubeb_jni_ptr->s_audio_manager_class);
delete cubeb_jni_ptr;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef _CUBEB_JNI_H_
#define _CUBEB_JNI_H_
typedef struct cubeb_jni cubeb_jni;
cubeb_jni *
cubeb_jni_init();
int
cubeb_get_output_latency_from_jni(cubeb_jni * cubeb_jni_ptr);
void
cubeb_jni_destroy(cubeb_jni * cubeb_jni_ptr);
#endif // _CUBEB_JNI_H_
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef _CUBEB_SLES_H_
#define _CUBEB_SLES_H_
#include <SLES/OpenSLES.h>
static SLresult
cubeb_get_sles_engine(SLObjectItf * pEngine, SLuint32 numOptions,
const SLEngineOption * pEngineOptions,
SLuint32 numInterfaces,
const SLInterfaceID * pInterfaceIds,
const SLboolean * pInterfaceRequired)
{
return slCreateEngine(pEngine, numOptions, pEngineOptions, numInterfaces,
pInterfaceIds, pInterfaceRequired);
}
static void
cubeb_destroy_sles_engine(SLObjectItf * self)
{
if (*self != NULL) {
(**self)->Destroy(*self);
*self = NULL;
}
}
static SLresult
cubeb_realize_sles_engine(SLObjectItf self)
{
return (*self)->Realize(self, SL_BOOLEAN_FALSE);
}
#endif
+1
View File
@@ -0,0 +1 @@
#include <speex/speex_resampler.h>
+766
View File
@@ -0,0 +1,766 @@
/*
* Copyright © 2013 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#undef NDEBUG
#include "cubeb/cubeb.h"
#include "cubeb-internal.h"
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define NELEMS(x) ((int)(sizeof(x) / sizeof(x[0])))
struct cubeb {
struct cubeb_ops * ops;
};
struct cubeb_stream {
/*
* Note: All implementations of cubeb_stream must keep the following
* layout.
*/
struct cubeb * context;
void * user_ptr;
};
#if defined(USE_PULSE)
int
pulse_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_PULSE_RUST)
int
pulse_rust_init(cubeb ** contet, char const * context_name);
#endif
#if defined(USE_JACK)
int
jack_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_ALSA)
int
alsa_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_AUDIOUNIT)
int
audiounit_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_AUDIOUNIT_RUST)
int
audiounit_rust_init(cubeb ** contet, char const * context_name);
#endif
#if defined(USE_WINMM)
int
winmm_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_WASAPI)
int
wasapi_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_SNDIO)
int
sndio_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_SUN)
int
sun_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_OPENSL)
int
opensl_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_OSS)
int
oss_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_AAUDIO)
int
aaudio_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_AUDIOTRACK)
int
audiotrack_init(cubeb ** context, char const * context_name);
#endif
#if defined(USE_KAI)
int
kai_init(cubeb ** context, char const * context_name);
#endif
static int
validate_stream_params(cubeb_stream_params * input_stream_params,
cubeb_stream_params * output_stream_params)
{
XASSERT(input_stream_params || output_stream_params);
if (output_stream_params) {
if (output_stream_params->rate < 1000 ||
output_stream_params->rate > 192000 ||
output_stream_params->channels < 1 ||
output_stream_params->channels > UINT8_MAX) {
return CUBEB_ERROR_INVALID_FORMAT;
}
}
if (input_stream_params) {
if (input_stream_params->rate < 1000 ||
input_stream_params->rate > 192000 ||
input_stream_params->channels < 1 ||
input_stream_params->channels > UINT8_MAX) {
return CUBEB_ERROR_INVALID_FORMAT;
}
}
// Rate and sample format must be the same for input and output, if using a
// duplex stream
if (input_stream_params && output_stream_params) {
if (input_stream_params->rate != output_stream_params->rate ||
input_stream_params->format != output_stream_params->format) {
return CUBEB_ERROR_INVALID_FORMAT;
}
}
cubeb_stream_params * params =
input_stream_params ? input_stream_params : output_stream_params;
switch (params->format) {
case CUBEB_SAMPLE_S16LE:
case CUBEB_SAMPLE_S16BE:
case CUBEB_SAMPLE_FLOAT32LE:
case CUBEB_SAMPLE_FLOAT32BE:
return CUBEB_OK;
}
return CUBEB_ERROR_INVALID_FORMAT;
}
static int
validate_latency(int latency)
{
if (latency < 1 || latency > 96000) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
return CUBEB_OK;
}
int
cubeb_init(cubeb ** context, char const * context_name,
char const * backend_name)
{
int (*init_oneshot)(cubeb **, char const *) = NULL;
if (backend_name != NULL) {
if (!strcmp(backend_name, "pulse")) {
#if defined(USE_PULSE)
init_oneshot = pulse_init;
#endif
} else if (!strcmp(backend_name, "pulse-rust")) {
#if defined(USE_PULSE_RUST)
init_oneshot = pulse_rust_init;
#endif
} else if (!strcmp(backend_name, "jack")) {
#if defined(USE_JACK)
init_oneshot = jack_init;
#endif
} else if (!strcmp(backend_name, "alsa")) {
#if defined(USE_ALSA)
init_oneshot = alsa_init;
#endif
} else if (!strcmp(backend_name, "audiounit")) {
#if defined(USE_AUDIOUNIT)
init_oneshot = audiounit_init;
#endif
} else if (!strcmp(backend_name, "audiounit-rust")) {
#if defined(USE_AUDIOUNIT_RUST)
init_oneshot = audiounit_rust_init;
#endif
} else if (!strcmp(backend_name, "wasapi")) {
#if defined(USE_WASAPI)
init_oneshot = wasapi_init;
#endif
} else if (!strcmp(backend_name, "winmm")) {
#if defined(USE_WINMM)
init_oneshot = winmm_init;
#endif
} else if (!strcmp(backend_name, "sndio")) {
#if defined(USE_SNDIO)
init_oneshot = sndio_init;
#endif
} else if (!strcmp(backend_name, "sun")) {
#if defined(USE_SUN)
init_oneshot = sun_init;
#endif
} else if (!strcmp(backend_name, "opensl")) {
#if defined(USE_OPENSL)
init_oneshot = opensl_init;
#endif
} else if (!strcmp(backend_name, "oss")) {
#if defined(USE_OSS)
init_oneshot = oss_init;
#endif
} else if (!strcmp(backend_name, "aaudio")) {
#if defined(USE_AAUDIO)
init_oneshot = aaudio_init;
#endif
} else if (!strcmp(backend_name, "audiotrack")) {
#if defined(USE_AUDIOTRACK)
init_oneshot = audiotrack_init;
#endif
} else if (!strcmp(backend_name, "kai")) {
#if defined(USE_KAI)
init_oneshot = kai_init;
#endif
} else {
/* Already set */
}
}
int (*default_init[])(cubeb **, char const *) = {
/*
* init_oneshot must be at the top to allow user
* to override all other choices
*/
init_oneshot,
#if defined(USE_PULSE_RUST)
pulse_rust_init,
#endif
#if defined(USE_PULSE)
pulse_init,
#endif
#if defined(USE_JACK)
jack_init,
#endif
#if defined(USE_SNDIO)
sndio_init,
#endif
#if defined(USE_ALSA)
alsa_init,
#endif
#if defined(USE_OSS)
oss_init,
#endif
#if defined(USE_AUDIOUNIT_RUST)
audiounit_rust_init,
#endif
#if defined(USE_AUDIOUNIT)
audiounit_init,
#endif
#if defined(USE_WASAPI)
wasapi_init,
#endif
#if defined(USE_WINMM)
winmm_init,
#endif
#if defined(USE_SUN)
sun_init,
#endif
#if defined(USE_OPENSL)
opensl_init,
#endif
// TODO: should probably be preferred over OpenSLES when available.
// Initialization will fail on old android devices.
#if defined(USE_AAUDIO)
aaudio_init,
#endif
#if defined(USE_AUDIOTRACK)
audiotrack_init,
#endif
#if defined(USE_KAI)
kai_init,
#endif
};
int i;
if (!context) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
#define OK(fn) assert((*context)->ops->fn)
for (i = 0; i < NELEMS(default_init); ++i) {
if (default_init[i] && default_init[i](context, context_name) == CUBEB_OK) {
/* Assert that the minimal API is implemented. */
OK(get_backend_id);
OK(destroy);
OK(stream_init);
OK(stream_destroy);
OK(stream_start);
OK(stream_stop);
OK(stream_get_position);
return CUBEB_OK;
}
}
return CUBEB_ERROR;
}
const char* const*
cubeb_get_backend_names()
{
static const char* backend_names[] = {
#if defined(USE_PULSE)
"pulse",
#endif
#if defined(USE_PULSE_RUST)
"pulse-rust",
#endif
#if defined(USE_JACK)
"jack",
#endif
#if defined(USE_ALSA)
"alsa",
#endif
#if defined(USE_AUDIOUNIT)
"audiounit",
#endif
#if defined(USE_AUDIOUNIT_RUST)
"audiounit-rust",
#endif
#if defined(USE_WASAPI)
"wasapi",
#endif
#if defined(USE_WINMM)
"winmm",
#endif
#if defined(USE_SNDIO)
"sndio",
#endif
#if defined(USE_SUN)
"sun",
#endif
#if defined(USE_OPENSL)
"opensl",
#endif
#if defined(USE_OSS)
"oss",
#endif
#if defined(USE_AAUDIO)
"aaudio",
#endif
#if defined(USE_AUDIOTRACK)
"audiotrack",
#endif
#if defined(USE_KAI)
"kai",
#endif
NULL,
};
return backend_names;
}
char const *
cubeb_get_backend_id(cubeb * context)
{
if (!context) {
return NULL;
}
return context->ops->get_backend_id(context);
}
int
cubeb_get_max_channel_count(cubeb * context, uint32_t * max_channels)
{
if (!context || !max_channels) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!context->ops->get_max_channel_count) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return context->ops->get_max_channel_count(context, max_channels);
}
int
cubeb_get_min_latency(cubeb * context, cubeb_stream_params * params,
uint32_t * latency_ms)
{
if (!context || !params || !latency_ms) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!context->ops->get_min_latency) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return context->ops->get_min_latency(context, *params, latency_ms);
}
int
cubeb_get_preferred_sample_rate(cubeb * context, uint32_t * rate)
{
if (!context || !rate) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!context->ops->get_preferred_sample_rate) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return context->ops->get_preferred_sample_rate(context, rate);
}
void
cubeb_destroy(cubeb * context)
{
if (!context) {
return;
}
context->ops->destroy(context);
}
int
cubeb_stream_init(cubeb * context, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
unsigned int latency, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr)
{
int r;
if (!context || !stream || !data_callback || !state_callback) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if ((r = validate_stream_params(input_stream_params, output_stream_params)) !=
CUBEB_OK ||
(r = validate_latency(latency)) != CUBEB_OK) {
return r;
}
r = context->ops->stream_init(context, stream, stream_name, input_device,
input_stream_params, output_device,
output_stream_params, latency, data_callback,
state_callback, user_ptr);
if (r == CUBEB_ERROR_INVALID_FORMAT) {
LOG("Invalid format, %p %p %d %d", output_stream_params,
input_stream_params,
output_stream_params && output_stream_params->format,
input_stream_params && input_stream_params->format);
}
return r;
}
void
cubeb_stream_destroy(cubeb_stream * stream)
{
if (!stream) {
return;
}
stream->context->ops->stream_destroy(stream);
}
int
cubeb_stream_start(cubeb_stream * stream)
{
if (!stream) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
return stream->context->ops->stream_start(stream);
}
int
cubeb_stream_stop(cubeb_stream * stream)
{
if (!stream) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
return stream->context->ops->stream_stop(stream);
}
int
cubeb_stream_get_position(cubeb_stream * stream, uint64_t * position)
{
if (!stream || !position) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
return stream->context->ops->stream_get_position(stream, position);
}
int
cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
{
if (!stream || !latency) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_get_latency) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_get_latency(stream, latency);
}
int
cubeb_stream_get_input_latency(cubeb_stream * stream, uint32_t * latency)
{
if (!stream || !latency) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_get_input_latency) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_get_input_latency(stream, latency);
}
int
cubeb_stream_set_volume(cubeb_stream * stream, float volume)
{
if (!stream || volume > 1.0 || volume < 0.0) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_set_volume) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_set_volume(stream, volume);
}
int
cubeb_stream_set_name(cubeb_stream * stream, char const * stream_name)
{
if (!stream || !stream_name) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_set_name) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_set_name(stream, stream_name);
}
int
cubeb_stream_get_current_device(cubeb_stream * stream,
cubeb_device ** const device)
{
if (!stream || !device) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_get_current_device) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_get_current_device(stream, device);
}
int
cubeb_stream_device_destroy(cubeb_stream * stream, cubeb_device * device)
{
if (!stream || !device) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_device_destroy) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_device_destroy(stream, device);
}
int
cubeb_stream_register_device_changed_callback(
cubeb_stream * stream,
cubeb_device_changed_callback device_changed_callback)
{
if (!stream) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (!stream->context->ops->stream_register_device_changed_callback) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return stream->context->ops->stream_register_device_changed_callback(
stream, device_changed_callback);
}
void *
cubeb_stream_user_ptr(cubeb_stream * stream)
{
if (!stream) {
return NULL;
}
return stream->user_ptr;
}
static void
log_device(cubeb_device_info * device_info)
{
char devfmts[128] = "";
const char *devtype, *devstate, *devdeffmt;
switch (device_info->type) {
case CUBEB_DEVICE_TYPE_INPUT:
devtype = "input";
break;
case CUBEB_DEVICE_TYPE_OUTPUT:
devtype = "output";
break;
case CUBEB_DEVICE_TYPE_UNKNOWN:
default:
devtype = "unknown?";
break;
};
switch (device_info->state) {
case CUBEB_DEVICE_STATE_DISABLED:
devstate = "disabled";
break;
case CUBEB_DEVICE_STATE_UNPLUGGED:
devstate = "unplugged";
break;
case CUBEB_DEVICE_STATE_ENABLED:
devstate = "enabled";
break;
default:
devstate = "unknown?";
break;
};
switch (device_info->default_format) {
case CUBEB_DEVICE_FMT_S16LE:
devdeffmt = "S16LE";
break;
case CUBEB_DEVICE_FMT_S16BE:
devdeffmt = "S16BE";
break;
case CUBEB_DEVICE_FMT_F32LE:
devdeffmt = "F32LE";
break;
case CUBEB_DEVICE_FMT_F32BE:
devdeffmt = "F32BE";
break;
default:
devdeffmt = "unknown?";
break;
};
if (device_info->format & CUBEB_DEVICE_FMT_S16LE) {
strcat(devfmts, " S16LE");
}
if (device_info->format & CUBEB_DEVICE_FMT_S16BE) {
strcat(devfmts, " S16BE");
}
if (device_info->format & CUBEB_DEVICE_FMT_F32LE) {
strcat(devfmts, " F32LE");
}
if (device_info->format & CUBEB_DEVICE_FMT_F32BE) {
strcat(devfmts, " F32BE");
}
LOG("DeviceID: \"%s\"%s\n"
"\tName:\t\"%s\"\n"
"\tGroup:\t\"%s\"\n"
"\tVendor:\t\"%s\"\n"
"\tType:\t%s\n"
"\tState:\t%s\n"
"\tMaximum channels:\t%u\n"
"\tFormat:\t%s (0x%x) (default: %s)\n"
"\tRate:\t[%u, %u] (default: %u)\n"
"\tLatency: lo %u frames, hi %u frames",
device_info->device_id, device_info->preferred ? " (PREFERRED)" : "",
device_info->friendly_name, device_info->group_id,
device_info->vendor_name, devtype, devstate, device_info->max_channels,
(devfmts[0] == '\0') ? devfmts : devfmts + 1,
(unsigned int)device_info->format, devdeffmt, device_info->min_rate,
device_info->max_rate, device_info->default_rate, device_info->latency_lo,
device_info->latency_hi);
}
int
cubeb_enumerate_devices(cubeb * context, cubeb_device_type devtype,
cubeb_device_collection * collection)
{
int rv;
if ((devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
return CUBEB_ERROR_INVALID_PARAMETER;
if (context == NULL || collection == NULL)
return CUBEB_ERROR_INVALID_PARAMETER;
if (!context->ops->enumerate_devices)
return CUBEB_ERROR_NOT_SUPPORTED;
rv = context->ops->enumerate_devices(context, devtype, collection);
if (cubeb_log_get_callback()) {
for (size_t i = 0; i < collection->count; i++) {
log_device(&collection->device[i]);
}
}
return rv;
}
int
cubeb_device_collection_destroy(cubeb * context,
cubeb_device_collection * collection)
{
int r;
if (context == NULL || collection == NULL)
return CUBEB_ERROR_INVALID_PARAMETER;
if (!context->ops->device_collection_destroy)
return CUBEB_ERROR_NOT_SUPPORTED;
if (!collection->device)
return CUBEB_OK;
r = context->ops->device_collection_destroy(context, collection);
if (r == CUBEB_OK) {
collection->device = NULL;
collection->count = 0;
}
return r;
}
int
cubeb_register_device_collection_changed(
cubeb * context, cubeb_device_type devtype,
cubeb_device_collection_changed_callback callback, void * user_ptr)
{
if (context == NULL ||
(devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
return CUBEB_ERROR_INVALID_PARAMETER;
if (!context->ops->register_device_collection_changed) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
return context->ops->register_device_collection_changed(context, devtype,
callback, user_ptr);
}
int
cubeb_set_log_callback(cubeb_log_level log_level,
cubeb_log_callback log_callback)
{
if (log_level < CUBEB_LOG_DISABLED || log_level > CUBEB_LOG_VERBOSE) {
return CUBEB_ERROR_INVALID_FORMAT;
}
if (!log_callback && log_level != CUBEB_LOG_DISABLED) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
if (cubeb_log_get_callback() && log_callback) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
cubeb_log_set(log_level, log_callback);
return CUBEB_OK;
}
File diff suppressed because it is too large Load Diff
+1487
View File
File diff suppressed because it is too large Load Diff
+17
View File
@@ -0,0 +1,17 @@
#ifndef CUBEB_ANDROID_H
#define CUBEB_ANDROID_H
#ifdef __cplusplus
extern "C" {
#endif
// If the latency requested is above this threshold, this stream is considered
// intended for playback (vs. real-time). Tell Android it should favor saving
// power over performance or latency.
// This is around 100ms at 44100 or 48000
const uint16_t POWERSAVE_LATENCY_FRAMES_THRESHOLD = 4000;
#ifdef __cplusplus
};
#endif
#endif // CUBEB_ANDROID_H
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_ARRAY_QUEUE_H
#define CUBEB_ARRAY_QUEUE_H
#include <assert.h>
#include <pthread.h>
#include <unistd.h>
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct {
void ** buf;
size_t num;
size_t writePos;
size_t readPos;
pthread_mutex_t mutex;
} array_queue;
array_queue *
array_queue_create(size_t num)
{
assert(num != 0);
array_queue * new_queue = (array_queue *)calloc(1, sizeof(array_queue));
new_queue->buf = (void **)calloc(1, sizeof(void *) * num);
new_queue->readPos = 0;
new_queue->writePos = 0;
new_queue->num = num;
pthread_mutex_init(&new_queue->mutex, NULL);
return new_queue;
}
void
array_queue_destroy(array_queue * aq)
{
assert(aq);
free(aq->buf);
pthread_mutex_destroy(&aq->mutex);
free(aq);
}
int
array_queue_push(array_queue * aq, void * item)
{
assert(item);
pthread_mutex_lock(&aq->mutex);
int ret = -1;
if (aq->buf[aq->writePos % aq->num] == NULL) {
aq->buf[aq->writePos % aq->num] = item;
aq->writePos = (aq->writePos + 1) % aq->num;
ret = 0;
}
// else queue is full
pthread_mutex_unlock(&aq->mutex);
return ret;
}
void *
array_queue_pop(array_queue * aq)
{
pthread_mutex_lock(&aq->mutex);
void * value = aq->buf[aq->readPos % aq->num];
if (value) {
aq->buf[aq->readPos % aq->num] = NULL;
aq->readPos = (aq->readPos + 1) % aq->num;
}
pthread_mutex_unlock(&aq->mutex);
return value;
}
size_t
array_queue_get_size(array_queue * aq)
{
pthread_mutex_lock(&aq->mutex);
ssize_t r = aq->writePos - aq->readPos;
if (r < 0) {
r = aq->num + r;
assert(r >= 0);
}
pthread_mutex_unlock(&aq->mutex);
return (size_t)r;
}
#if defined(__cplusplus)
}
#endif
#endif // CUBE_ARRAY_QUEUE_H
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright © 2017 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_ASSERT
#define CUBEB_ASSERT
#include <stdio.h>
#include <stdlib.h>
/**
* This allow using an external release assert method. This file should only
* export a function or macro called XASSERT that aborts the program.
*/
#define XASSERT(expr) \
do { \
if (!(expr)) { \
fprintf(stderr, "%s:%d - fatal error: %s\n", __FILE__, __LINE__, #expr); \
abort(); \
} \
} while (0)
#endif
+472
View File
@@ -0,0 +1,472 @@
/*
* Copyright © 2013 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(NDEBUG)
#define NDEBUG
#endif
#include <android/log.h>
#include <assert.h>
#include <dlfcn.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include "android/audiotrack_definitions.h"
#include "cubeb-internal.h"
#include "cubeb/cubeb.h"
#ifndef ALOG
#if defined(DEBUG) || defined(FORCE_ALOG)
#define ALOG(args...) \
__android_log_print(ANDROID_LOG_INFO, "Gecko - Cubeb", ##args)
#else
#define ALOG(args...)
#endif
#endif
/**
* A lot of bytes for safety. It should be possible to bring this down a bit. */
#define SIZE_AUDIOTRACK_INSTANCE 256
/**
* call dlsym to get the symbol |mangled_name|, handle the error and store the
* pointer in |pointer|. Because depending on Android version, we want different
* symbols, not finding a symbol is not an error. */
#define DLSYM_DLERROR(mangled_name, pointer, lib) \
do { \
pointer = dlsym(lib, mangled_name); \
if (!pointer) { \
ALOG("error while loading %stm: %stm\n", mangled_name, dlerror()); \
} else { \
ALOG("%stm: OK", mangled_name); \
} \
} while (0);
static struct cubeb_ops const audiotrack_ops;
void
audiotrack_destroy(cubeb * context);
void
audiotrack_stream_destroy(cubeb_stream * stream);
struct AudioTrack {
/* only available on ICS and later. The second int paramter is in fact of type
* audio_stream_type_t. */
/* static */ status_t (*get_min_frame_count)(int * frame_count,
int stream_type, uint32_t rate);
/* if we have a recent ctor, but can't find the above symbol, we
* can get the minimum frame count with this signature, and we are
* running gingerbread. */
/* static */ status_t (*get_min_frame_count_gingerbread)(int * frame_count,
int stream_type,
uint32_t rate);
void * (*ctor)(void * instance, int, unsigned int, int, int, int,
unsigned int, void (*)(int, void *, void *), void *, int, int);
void * (*dtor)(void * instance);
void (*start)(void * instance);
void (*pause)(void * instance);
uint32_t (*latency)(void * instance);
status_t (*check)(void * instance);
status_t (*get_position)(void * instance, uint32_t * position);
/* static */ int (*get_output_samplingrate)(int * samplerate, int stream);
status_t (*set_marker_position)(void * instance, unsigned int);
status_t (*set_volume)(void * instance, float left, float right);
};
struct cubeb {
struct cubeb_ops const * ops;
void * library;
struct AudioTrack klass;
};
struct cubeb_stream {
/* Note: Must match cubeb_stream layout in cubeb.c. */
cubeb * context;
void * user_ptr;
/**/
cubeb_stream_params params;
cubeb_data_callback data_callback;
cubeb_state_callback state_callback;
void * instance;
/* Number of frames that have been passed to the AudioTrack callback */
long unsigned written;
int draining;
};
static void
audiotrack_refill(int event, void * user, void * info)
{
cubeb_stream * stream = user;
switch (event) {
case EVENT_MORE_DATA: {
long got = 0;
struct Buffer * b = (struct Buffer *)info;
if (stream->draining) {
return;
}
got = stream->data_callback(stream, stream->user_ptr, NULL, b->raw,
b->frameCount);
stream->written += got;
if (got != (long)b->frameCount) {
stream->draining = 1;
/* set a marker so we are notified when the are done draining, that is,
* when every frame has been played by android. */
stream->context->klass.set_marker_position(stream->instance,
stream->written);
}
break;
}
case EVENT_UNDERRUN:
ALOG("underrun in cubeb backend.");
break;
case EVENT_LOOP_END:
assert(0 && "We don't support the loop feature of audiotrack.");
break;
case EVENT_MARKER:
assert(stream->draining);
stream->state_callback(stream, stream->user_ptr, CUBEB_STATE_DRAINED);
break;
case EVENT_NEW_POS:
assert(
0 &&
"We don't support the setPositionUpdatePeriod feature of audiotrack.");
break;
case EVENT_BUFFER_END:
assert(0 && "Should not happen.");
break;
}
}
/* We are running on gingerbread if we found the gingerbread signature for
* getMinFrameCount */
static int
audiotrack_version_is_gingerbread(cubeb * ctx)
{
return ctx->klass.get_min_frame_count_gingerbread != NULL;
}
int
audiotrack_get_min_frame_count(cubeb * ctx, cubeb_stream_params * params,
int * min_frame_count)
{
status_t status;
/* Recent Android have a getMinFrameCount method. */
if (!audiotrack_version_is_gingerbread(ctx)) {
status = ctx->klass.get_min_frame_count(
min_frame_count, AUDIO_STREAM_TYPE_MUSIC, params->rate);
} else {
status = ctx->klass.get_min_frame_count_gingerbread(
min_frame_count, AUDIO_STREAM_TYPE_MUSIC, params->rate);
}
if (status != 0) {
ALOG("error getting the min frame count");
return CUBEB_ERROR;
}
return CUBEB_OK;
}
int
audiotrack_init(cubeb ** context, char const * context_name)
{
cubeb * ctx;
struct AudioTrack * c;
assert(context);
*context = NULL;
ctx = calloc(1, sizeof(*ctx));
assert(ctx);
/* If we use an absolute path here ("/system/lib/libmedia.so"), and on Android
* 2.2, the dlopen succeeds, all the dlsym succeed, but a segfault happens on
* the first call to a dlsym'ed function. Somehow this does not happen when
* using only the name of the library. */
ctx->library = dlopen("libmedia.so", RTLD_LAZY);
if (!ctx->library) {
ALOG("dlopen error: %s.", dlerror());
free(ctx);
return CUBEB_ERROR;
}
/* Recent Android first, then Gingerbread. */
DLSYM_DLERROR("_ZN7android10AudioTrackC1EijiiijPFviPvS1_ES1_ii",
ctx->klass.ctor, ctx->library);
DLSYM_DLERROR("_ZN7android10AudioTrackD1Ev", ctx->klass.dtor, ctx->library);
DLSYM_DLERROR("_ZNK7android10AudioTrack7latencyEv", ctx->klass.latency,
ctx->library);
DLSYM_DLERROR("_ZNK7android10AudioTrack9initCheckEv", ctx->klass.check,
ctx->library);
DLSYM_DLERROR("_ZN7android11AudioSystem21getOutputSamplingRateEPii",
ctx->klass.get_output_samplingrate, ctx->library);
/* |getMinFrameCount| is available on gingerbread and ICS with different
* signatures. */
DLSYM_DLERROR(
"_ZN7android10AudioTrack16getMinFrameCountEPi19audio_stream_type_tj",
ctx->klass.get_min_frame_count, ctx->library);
if (!ctx->klass.get_min_frame_count) {
DLSYM_DLERROR("_ZN7android10AudioTrack16getMinFrameCountEPiij",
ctx->klass.get_min_frame_count_gingerbread, ctx->library);
}
DLSYM_DLERROR("_ZN7android10AudioTrack5startEv", ctx->klass.start,
ctx->library);
DLSYM_DLERROR("_ZN7android10AudioTrack5pauseEv", ctx->klass.pause,
ctx->library);
DLSYM_DLERROR("_ZN7android10AudioTrack11getPositionEPj",
ctx->klass.get_position, ctx->library);
DLSYM_DLERROR("_ZN7android10AudioTrack17setMarkerPositionEj",
ctx->klass.set_marker_position, ctx->library);
DLSYM_DLERROR("_ZN7android10AudioTrack9setVolumeEff", ctx->klass.set_volume,
ctx->library);
/* check that we have a combination of symbol that makes sense */
c = &ctx->klass;
if (!(c->ctor && c->dtor && c->latency && c->check &&
/* at least one way to get the minimum frame count to request. */
(c->get_min_frame_count || c->get_min_frame_count_gingerbread) &&
c->start && c->pause && c->get_position && c->set_marker_position)) {
ALOG("Could not find all the symbols we need.");
audiotrack_destroy(ctx);
return CUBEB_ERROR;
}
ctx->ops = &audiotrack_ops;
*context = ctx;
return CUBEB_OK;
}
char const *
audiotrack_get_backend_id(cubeb * context)
{
return "audiotrack";
}
static int
audiotrack_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
{
assert(ctx && max_channels);
/* The android mixer handles up to two channels, see
http://androidxref.com/4.2.2_r1/xref/frameworks/av/services/audioflinger/AudioFlinger.h#67
*/
*max_channels = 2;
return CUBEB_OK;
}
static int
audiotrack_get_min_latency(cubeb * ctx, cubeb_stream_params params,
uint32_t * latency_ms)
{
/* We always use the lowest latency possible when using this backend (see
* audiotrack_stream_init), so this value is not going to be used. */
int r;
r = audiotrack_get_min_frame_count(ctx, &params, (int *)latency_ms);
if (r != CUBEB_OK) {
return CUBEB_ERROR;
}
return CUBEB_OK;
}
static int
audiotrack_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
{
status_t r;
r = ctx->klass.get_output_samplingrate((int32_t *)rate, 3 /* MUSIC */);
return r == 0 ? CUBEB_OK : CUBEB_ERROR;
}
void
audiotrack_destroy(cubeb * context)
{
assert(context);
dlclose(context->library);
free(context);
}
int
audiotrack_stream_init(cubeb * ctx, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
unsigned int latency, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr)
{
cubeb_stream * stm;
int32_t channels;
uint32_t min_frame_count;
assert(ctx && stream);
assert(!input_stream_params && "not supported");
if (input_device || output_device) {
/* Device selection not yet implemented. */
return CUBEB_ERROR_DEVICE_UNAVAILABLE;
}
if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE ||
output_stream_params->format == CUBEB_SAMPLE_FLOAT32BE) {
return CUBEB_ERROR_INVALID_FORMAT;
}
if (audiotrack_get_min_frame_count(ctx, output_stream_params,
(int *)&min_frame_count)) {
return CUBEB_ERROR;
}
stm = calloc(1, sizeof(*stm));
assert(stm);
stm->context = ctx;
stm->data_callback = data_callback;
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
stm->params = *output_stream_params;
stm->instance = calloc(SIZE_AUDIOTRACK_INSTANCE, 1);
(*(uint32_t *)((intptr_t)stm->instance + SIZE_AUDIOTRACK_INSTANCE - 4)) =
0xbaadbaad;
assert(stm->instance && "cubeb: EOM");
/* gingerbread uses old channel layout enum */
if (audiotrack_version_is_gingerbread(ctx)) {
channels = stm->params.channels == 2 ? AUDIO_CHANNEL_OUT_STEREO_Legacy
: AUDIO_CHANNEL_OUT_MONO_Legacy;
} else {
channels = stm->params.channels == 2 ? AUDIO_CHANNEL_OUT_STEREO_ICS
: AUDIO_CHANNEL_OUT_MONO_ICS;
}
ctx->klass.ctor(stm->instance, AUDIO_STREAM_TYPE_MUSIC, stm->params.rate,
AUDIO_FORMAT_PCM_16_BIT, channels, min_frame_count, 0,
audiotrack_refill, stm, 0, 0);
assert((*(uint32_t *)((intptr_t)stm->instance + SIZE_AUDIOTRACK_INSTANCE -
4)) == 0xbaadbaad);
if (ctx->klass.check(stm->instance)) {
ALOG("stream not initialized properly.");
audiotrack_stream_destroy(stm);
return CUBEB_ERROR;
}
*stream = stm;
return CUBEB_OK;
}
void
audiotrack_stream_destroy(cubeb_stream * stream)
{
assert(stream->context);
stream->context->klass.dtor(stream->instance);
free(stream->instance);
stream->instance = NULL;
free(stream);
}
int
audiotrack_stream_start(cubeb_stream * stream)
{
assert(stream->instance);
stream->context->klass.start(stream->instance);
stream->state_callback(stream, stream->user_ptr, CUBEB_STATE_STARTED);
return CUBEB_OK;
}
int
audiotrack_stream_stop(cubeb_stream * stream)
{
assert(stream->instance);
stream->context->klass.pause(stream->instance);
stream->state_callback(stream, stream->user_ptr, CUBEB_STATE_STOPPED);
return CUBEB_OK;
}
int
audiotrack_stream_get_position(cubeb_stream * stream, uint64_t * position)
{
uint32_t p;
assert(stream->instance && position);
stream->context->klass.get_position(stream->instance, &p);
*position = p;
return CUBEB_OK;
}
int
audiotrack_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
{
assert(stream->instance && latency);
/* Android returns the latency in ms, we want it in frames. */
*latency = stream->context->klass.latency(stream->instance);
/* with rate <= 96000, we won't overflow until 44.739 seconds of latency */
*latency = (*latency * stream->params.rate) / 1000;
return 0;
}
int
audiotrack_stream_set_volume(cubeb_stream * stream, float volume)
{
status_t status;
status = stream->context->klass.set_volume(stream->instance, volume, volume);
if (status) {
return CUBEB_ERROR;
}
return CUBEB_OK;
}
static struct cubeb_ops const audiotrack_ops = {
.init = audiotrack_init,
.get_backend_id = audiotrack_get_backend_id,
.get_max_channel_count = audiotrack_get_max_channel_count,
.get_min_latency = audiotrack_get_min_latency,
.get_preferred_sample_rate = audiotrack_get_preferred_sample_rate,
.enumerate_devices = NULL,
.device_collection_destroy = NULL,
.destroy = audiotrack_destroy,
.stream_init = audiotrack_stream_init,
.stream_destroy = audiotrack_stream_destroy,
.stream_start = audiotrack_stream_start,
.stream_stop = audiotrack_stream_stop,
.stream_get_position = audiotrack_stream_get_position,
.stream_get_latency = audiotrack_stream_get_latency,
.stream_get_input_latency = NULL,
.stream_set_volume = audiotrack_stream_set_volume,
.stream_set_name = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL};
File diff suppressed because it is too large Load Diff
+1166
View File
File diff suppressed because it is too large Load Diff
+369
View File
@@ -0,0 +1,369 @@
/*
* Copyright © 2015 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/fmutex.h>
#include <kai.h>
#include "cubeb-internal.h"
#include "cubeb/cubeb.h"
/* We don't support more than 2 channels in KAI */
#define MAX_CHANNELS 2
#define NBUFS 2
#define FRAME_SIZE 2048
struct cubeb_stream_item {
cubeb_stream * stream;
};
static struct cubeb_ops const kai_ops;
struct cubeb {
struct cubeb_ops const * ops;
};
struct cubeb_stream {
/* Note: Must match cubeb_stream layout in cubeb.c. */
cubeb * context;
void * user_ptr;
/**/
cubeb_stream_params params;
cubeb_data_callback data_callback;
cubeb_state_callback state_callback;
HKAI hkai;
KAISPEC spec;
uint64_t total_frames;
float soft_volume;
_fmutex mutex;
float float_buffer[FRAME_SIZE * MAX_CHANNELS];
};
static inline long
frames_to_bytes(long frames, cubeb_stream_params params)
{
return frames * 2 * params.channels; /* 2 bytes per frame */
}
static inline long
bytes_to_frames(long bytes, cubeb_stream_params params)
{
return bytes / 2 / params.channels; /* 2 bytes per frame */
}
static void
kai_destroy(cubeb * ctx);
/*static*/ int
kai_init(cubeb ** context, char const * context_name)
{
cubeb * ctx;
XASSERT(context);
*context = NULL;
if (kaiInit(KAIM_AUTO))
return CUBEB_ERROR;
ctx = calloc(1, sizeof(*ctx));
XASSERT(ctx);
ctx->ops = &kai_ops;
*context = ctx;
return CUBEB_OK;
}
static char const *
kai_get_backend_id(cubeb * ctx)
{
return "kai";
}
static void
kai_destroy(cubeb * ctx)
{
kaiDone();
free(ctx);
}
static void
float_to_s16ne(int16_t * dst, float * src, size_t n)
{
long l;
while (n--) {
l = lrintf(*src++ * 0x8000);
if (l > 32767)
l = 32767;
if (l < -32768)
l = -32768;
*dst++ = (int16_t)l;
}
}
static ULONG APIENTRY
kai_callback(PVOID cbdata, PVOID buffer, ULONG len)
{
cubeb_stream * stm = cbdata;
void * p;
long wanted_frames;
long frames;
float soft_volume;
int elements = len / sizeof(int16_t);
p = stm->params.format == CUBEB_SAMPLE_FLOAT32NE ? stm->float_buffer : buffer;
wanted_frames = bytes_to_frames(len, stm->params);
frames = stm->data_callback(stm, stm->user_ptr, NULL, p, wanted_frames);
_fmutex_request(&stm->mutex, 0);
stm->total_frames += frames;
soft_volume = stm->soft_volume;
_fmutex_release(&stm->mutex);
if (frames < wanted_frames)
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED);
if (stm->params.format == CUBEB_SAMPLE_FLOAT32NE)
float_to_s16ne(buffer, p, elements);
if (soft_volume != -1.0f) {
int16_t * b = buffer;
int i;
for (i = 0; i < elements; i++)
*b++ *= soft_volume;
}
return frames_to_bytes(frames, stm->params);
}
static void
kai_stream_destroy(cubeb_stream * stm);
static int
kai_stream_init(cubeb * context, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
unsigned int latency, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr)
{
cubeb_stream * stm;
KAISPEC wanted_spec;
XASSERT(!input_stream_params && "not supported.");
if (input_device || output_device) {
/* Device selection not yet implemented. */
return CUBEB_ERROR_DEVICE_UNAVAILABLE;
}
if (!output_stream_params)
return CUBEB_ERROR_INVALID_PARAMETER;
// Loopback is unsupported
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
return CUBEB_ERROR_NOT_SUPPORTED;
}
if (output_stream_params->channels < 1 ||
output_stream_params->channels > MAX_CHANNELS)
return CUBEB_ERROR_INVALID_FORMAT;
XASSERT(context);
XASSERT(stream);
*stream = NULL;
stm = calloc(1, sizeof(*stm));
XASSERT(stm);
stm->context = context;
stm->params = *output_stream_params;
stm->data_callback = data_callback;
stm->state_callback = state_callback;
stm->user_ptr = user_ptr;
stm->soft_volume = -1.0f;
if (_fmutex_create(&stm->mutex, 0)) {
free(stm);
return CUBEB_ERROR;
}
wanted_spec.usDeviceIndex = 0;
wanted_spec.ulType = KAIT_PLAY;
wanted_spec.ulBitsPerSample = BPS_16;
wanted_spec.ulSamplingRate = stm->params.rate;
wanted_spec.ulDataFormat = MCI_WAVE_FORMAT_PCM;
wanted_spec.ulChannels = stm->params.channels;
wanted_spec.ulNumBuffers = NBUFS;
wanted_spec.ulBufferSize = frames_to_bytes(FRAME_SIZE, stm->params);
wanted_spec.fShareable = TRUE;
wanted_spec.pfnCallBack = kai_callback;
wanted_spec.pCallBackData = stm;
if (kaiOpen(&wanted_spec, &stm->spec, &stm->hkai)) {
_fmutex_close(&stm->mutex);
free(stm);
return CUBEB_ERROR;
}
*stream = stm;
return CUBEB_OK;
}
static void
kai_stream_destroy(cubeb_stream * stm)
{
kaiClose(stm->hkai);
_fmutex_close(&stm->mutex);
free(stm);
}
static int
kai_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
{
XASSERT(ctx && max_channels);
*max_channels = MAX_CHANNELS;
return CUBEB_OK;
}
static int
kai_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latency)
{
/* We have at least two buffers. One is being played, the other one is being
filled. So there is as much latency as one buffer. */
*latency = FRAME_SIZE;
return CUBEB_OK;
}
static int
kai_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
{
cubeb_stream_params params;
KAISPEC wanted_spec;
KAISPEC spec;
HKAI hkai;
params.format = CUBEB_SAMPLE_S16NE;
params.rate = 48000;
params.channels = 2;
wanted_spec.usDeviceIndex = 0;
wanted_spec.ulType = KAIT_PLAY;
wanted_spec.ulBitsPerSample = BPS_16;
wanted_spec.ulSamplingRate = params.rate;
wanted_spec.ulDataFormat = MCI_WAVE_FORMAT_PCM;
wanted_spec.ulChannels = params.channels;
wanted_spec.ulNumBuffers = NBUFS;
wanted_spec.ulBufferSize = frames_to_bytes(FRAME_SIZE, params);
wanted_spec.fShareable = TRUE;
wanted_spec.pfnCallBack = kai_callback;
wanted_spec.pCallBackData = NULL;
/* Test 48KHz */
if (kaiOpen(&wanted_spec, &spec, &hkai)) {
/* Not supported. Fall back to 44.1KHz */
params.rate = 44100;
} else {
/* Supported. Use 48KHz */
kaiClose(hkai);
}
*rate = params.rate;
return CUBEB_OK;
}
static int
kai_stream_start(cubeb_stream * stm)
{
if (kaiPlay(stm->hkai))
return CUBEB_ERROR;
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STARTED);
return CUBEB_OK;
}
static int
kai_stream_stop(cubeb_stream * stm)
{
if (kaiStop(stm->hkai))
return CUBEB_ERROR;
stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED);
return CUBEB_OK;
}
static int
kai_stream_get_position(cubeb_stream * stm, uint64_t * position)
{
_fmutex_request(&stm->mutex, 0);
*position = stm->total_frames;
_fmutex_release(&stm->mutex);
return CUBEB_OK;
}
static int
kai_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
{
/* Out of buffers, one is being played, the others are being filled.
So there is as much latency as total buffers - 1. */
*latency = bytes_to_frames(stm->spec.ulBufferSize, stm->params) *
(stm->spec.ulNumBuffers - 1);
return CUBEB_OK;
}
static int
kai_stream_set_volume(cubeb_stream * stm, float volume)
{
_fmutex_request(&stm->mutex, 0);
stm->soft_volume = volume;
_fmutex_release(&stm->mutex);
return CUBEB_OK;
}
static struct cubeb_ops const kai_ops = {
/*.init =*/kai_init,
/*.get_backend_id =*/kai_get_backend_id,
/*.get_max_channel_count=*/kai_get_max_channel_count,
/*.get_min_latency=*/kai_get_min_latency,
/*.get_preferred_sample_rate =*/kai_get_preferred_sample_rate,
/*.get_preferred_channel_layout =*/NULL,
/*.enumerate_devices =*/NULL,
/*.device_collection_destroy =*/NULL,
/*.destroy =*/kai_destroy,
/*.stream_init =*/kai_stream_init,
/*.stream_destroy =*/kai_stream_destroy,
/*.stream_start =*/kai_stream_start,
/*.stream_stop =*/kai_stream_stop,
/*.stream_get_position =*/kai_stream_get_position,
/*.stream_get_latency = */ kai_stream_get_latency,
/*.stream_get_input_latency = */ NULL,
/*.stream_set_volume =*/kai_stream_set_volume,
/*.stream_set_name =*/NULL,
/*.stream_get_current_device =*/NULL,
/*.stream_device_destroy =*/NULL,
/*.stream_register_device_changed_callback=*/NULL,
/*.register_device_collection_changed=*/NULL};
+168
View File
@@ -0,0 +1,168 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#define NOMINMAX
#include "cubeb_log.h"
#include "cubeb_ringbuffer.h"
#include "cubeb_tracing.h"
#include <cstdarg>
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#endif
std::atomic<cubeb_log_level> g_cubeb_log_level;
std::atomic<cubeb_log_callback> g_cubeb_log_callback;
/** The maximum size of a log message, after having been formatted. */
const size_t CUBEB_LOG_MESSAGE_MAX_SIZE = 256;
/** The maximum number of log messages that can be queued before dropping
* messages. */
const size_t CUBEB_LOG_MESSAGE_QUEUE_DEPTH = 40;
/** Number of milliseconds to wait before dequeuing log messages. */
#define CUBEB_LOG_BATCH_PRINT_INTERVAL_MS 10
/**
* This wraps an inline buffer, that represents a log message, that must be
* null-terminated.
* This class should not use system calls or other potentially blocking code.
*/
class cubeb_log_message {
public:
cubeb_log_message() { *storage = '\0'; }
cubeb_log_message(char const str[CUBEB_LOG_MESSAGE_MAX_SIZE])
{
size_t length = strlen(str);
/* paranoia against malformed message */
assert(length < CUBEB_LOG_MESSAGE_MAX_SIZE);
if (length > CUBEB_LOG_MESSAGE_MAX_SIZE - 1) {
return;
}
PodCopy(storage, str, length);
storage[length] = '\0';
}
char const * get() { return storage; }
private:
char storage[CUBEB_LOG_MESSAGE_MAX_SIZE];
};
/** Lock-free asynchronous logger, made so that logging from a
* real-time audio callback does not block the audio thread. */
class cubeb_async_logger {
public:
/* This is thread-safe since C++11 */
static cubeb_async_logger & get()
{
static cubeb_async_logger instance;
return instance;
}
void push(char const str[CUBEB_LOG_MESSAGE_MAX_SIZE])
{
cubeb_log_message msg(str);
msg_queue.enqueue(msg);
}
void run()
{
std::thread([this]() {
CUBEB_REGISTER_THREAD("cubeb_log");
while (true) {
cubeb_log_message msg;
while (msg_queue.dequeue(&msg, 1)) {
cubeb_log_internal_no_format(msg.get());
}
#ifdef _WIN32
Sleep(CUBEB_LOG_BATCH_PRINT_INTERVAL_MS);
#else
timespec sleep_duration = sleep_for;
timespec remainder;
do {
if (nanosleep(&sleep_duration, &remainder) == 0 || errno != EINTR) {
break;
}
sleep_duration = remainder;
} while (remainder.tv_sec || remainder.tv_nsec);
#endif
}
CUBEB_UNREGISTER_THREAD();
}).detach();
}
// Tell the underlying queue the producer thread has changed, so it does not
// assert in debug. This should be called with the thread stopped.
void reset_producer_thread() { msg_queue.reset_thread_ids(); }
private:
#ifndef _WIN32
const struct timespec sleep_for = {
CUBEB_LOG_BATCH_PRINT_INTERVAL_MS / 1000,
(CUBEB_LOG_BATCH_PRINT_INTERVAL_MS % 1000) * 1000 * 1000};
#endif
cubeb_async_logger() : msg_queue(CUBEB_LOG_MESSAGE_QUEUE_DEPTH) { run(); }
/** This is quite a big data structure, but is only instantiated if the
* asynchronous logger is used.*/
lock_free_queue<cubeb_log_message> msg_queue;
};
void
cubeb_log_internal(char const * file, uint32_t line, char const * fmt, ...)
{
va_list args;
va_start(args, fmt);
char msg[CUBEB_LOG_MESSAGE_MAX_SIZE];
vsnprintf(msg, CUBEB_LOG_MESSAGE_MAX_SIZE, fmt, args);
g_cubeb_log_callback.load()("%s:%d:%s", file, line, msg);
va_end(args);
}
void
cubeb_log_internal_no_format(const char * msg)
{
g_cubeb_log_callback.load()(msg);
}
void
cubeb_async_log(char const * fmt, ...)
{
// This is going to copy a 256 bytes array around, which is fine.
// We don't want to allocate memory here, because this is made to
// be called from a real-time callback.
va_list args;
va_start(args, fmt);
char msg[CUBEB_LOG_MESSAGE_MAX_SIZE];
vsnprintf(msg, CUBEB_LOG_MESSAGE_MAX_SIZE, fmt, args);
cubeb_async_logger::get().push(msg);
va_end(args);
}
void
cubeb_async_log_reset_threads(void)
{
if (!g_cubeb_log_callback) {
return;
}
cubeb_async_logger::get().reset_producer_thread();
}
void
cubeb_log_set(cubeb_log_level log_level, cubeb_log_callback log_callback)
{
g_cubeb_log_level = log_level;
g_cubeb_log_callback = log_callback;
}
cubeb_log_level
cubeb_log_get_level()
{
return g_cubeb_log_level;
}
cubeb_log_callback
cubeb_log_get_callback()
{
return g_cubeb_log_callback;
}
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_LOG
#define CUBEB_LOG
#include "cubeb/cubeb.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__GNUC__) || defined(__clang__)
#define PRINTF_FORMAT(fmt, args) __attribute__((format(printf, fmt, args)))
#if defined(__FILE_NAME__)
#define __FILENAME__ __FILE_NAME__
#else
#define __FILENAME__ \
(__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 \
: __FILE__)
#endif
#else
#define PRINTF_FORMAT(fmt, args)
#include <string.h>
#define __FILENAME__ \
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
void
cubeb_log_set(cubeb_log_level log_level, cubeb_log_callback log_callback);
cubeb_log_level
cubeb_log_get_level();
cubeb_log_callback
cubeb_log_get_callback();
void
cubeb_log_internal_no_format(const char * msg);
void
cubeb_log_internal(const char * filename, uint32_t line, const char * fmt, ...);
void
cubeb_async_log(const char * fmt, ...);
void
cubeb_async_log_reset_threads(void);
#ifdef __cplusplus
}
#endif
#define LOGV(msg, ...) LOG_INTERNAL(CUBEB_LOG_VERBOSE, msg, ##__VA_ARGS__)
#define LOG(msg, ...) LOG_INTERNAL(CUBEB_LOG_NORMAL, msg, ##__VA_ARGS__)
#define LOG_INTERNAL(level, fmt, ...) \
do { \
if (cubeb_log_get_level() >= level && cubeb_log_get_callback()) { \
cubeb_log_internal(__FILENAME__, __LINE__, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define ALOG_INTERNAL(level, fmt, ...) \
do { \
if (cubeb_log_get_level() >= level && cubeb_log_get_callback()) { \
cubeb_async_log(fmt, ##__VA_ARGS__); \
} \
} while (0)
/* Asynchronous logging macros to log in real-time callbacks. */
/* Should not be used on android due to the use of global/static variables. */
#define ALOGV(msg, ...) ALOG_INTERNAL(CUBEB_LOG_VERBOSE, msg, ##__VA_ARGS__)
#define ALOG(msg, ...) ALOG_INTERNAL(CUBEB_LOG_NORMAL, msg, ##__VA_ARGS__)
#endif // CUBEB_LOG
+621
View File
@@ -0,0 +1,621 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*
* Adapted from code based on libswresample's rematrix.c
*/
#define NOMINMAX
#include "cubeb_mixer.h"
#include "cubeb-internal.h"
#include "cubeb_utils.h"
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdlib>
#include <memory>
#include <type_traits>
#ifndef FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
#endif
#define CHANNELS_MAX 32
#define FRONT_LEFT 0
#define FRONT_RIGHT 1
#define FRONT_CENTER 2
#define LOW_FREQUENCY 3
#define BACK_LEFT 4
#define BACK_RIGHT 5
#define FRONT_LEFT_OF_CENTER 6
#define FRONT_RIGHT_OF_CENTER 7
#define BACK_CENTER 8
#define SIDE_LEFT 9
#define SIDE_RIGHT 10
#define TOP_CENTER 11
#define TOP_FRONT_LEFT 12
#define TOP_FRONT_CENTER 13
#define TOP_FRONT_RIGHT 14
#define TOP_BACK_LEFT 15
#define TOP_BACK_CENTER 16
#define TOP_BACK_RIGHT 17
#define NUM_NAMED_CHANNELS 18
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#endif
#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
#define C30DB M_SQRT2
#define C15DB 1.189207115
#define C__0DB 1.0
#define C_15DB 0.840896415
#define C_30DB M_SQRT1_2
#define C_45DB 0.594603558
#define C_60DB 0.5
static cubeb_channel_layout
cubeb_channel_layout_check(cubeb_channel_layout l, uint32_t c)
{
if (l == CUBEB_LAYOUT_UNDEFINED) {
switch (c) {
case 1:
return CUBEB_LAYOUT_MONO;
case 2:
return CUBEB_LAYOUT_STEREO;
}
}
return l;
}
unsigned int
cubeb_channel_layout_nb_channels(cubeb_channel_layout x)
{
#if __GNUC__ || __clang__
return __builtin_popcount(x);
#else
x -= (x >> 1) & 0x55555555;
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x += x >> 8;
return (x + (x >> 16)) & 0x3F;
#endif
}
struct MixerContext {
MixerContext(cubeb_sample_format f, uint32_t in_channels,
cubeb_channel_layout in, uint32_t out_channels,
cubeb_channel_layout out)
: _format(f), _in_ch_layout(cubeb_channel_layout_check(in, in_channels)),
_out_ch_layout(cubeb_channel_layout_check(out, out_channels)),
_in_ch_count(in_channels), _out_ch_count(out_channels)
{
if (in_channels != cubeb_channel_layout_nb_channels(in) ||
out_channels != cubeb_channel_layout_nb_channels(out)) {
// Mismatch between channels and layout, aborting.
return;
}
_valid = init() >= 0;
}
static bool even(cubeb_channel_layout layout)
{
if (!layout) {
return true;
}
if (layout & (layout - 1)) {
return true;
}
return false;
}
// Ensure that the layout is sane (that is have symmetrical left/right
// channels), if not, layout will be treated as mono.
static cubeb_channel_layout clean_layout(cubeb_channel_layout layout)
{
if (layout && layout != CHANNEL_FRONT_LEFT && !(layout & (layout - 1))) {
LOG("Treating layout as mono");
return CHANNEL_FRONT_CENTER;
}
return layout;
}
static bool sane_layout(cubeb_channel_layout layout)
{
if (!(layout & CUBEB_LAYOUT_3F)) { // at least 1 front speaker
return false;
}
if (!even(layout & (CHANNEL_FRONT_LEFT |
CHANNEL_FRONT_RIGHT))) { // no asymetric front
return false;
}
if (!even(layout &
(CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT))) { // no asymetric side
return false;
}
if (!even(layout & (CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT))) {
return false;
}
if (!even(layout &
(CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER))) {
return false;
}
if (cubeb_channel_layout_nb_channels(layout) >= CHANNELS_MAX) {
return false;
}
return true;
}
int auto_matrix();
int init();
const cubeb_sample_format _format;
const cubeb_channel_layout _in_ch_layout; ///< input channel layout
const cubeb_channel_layout _out_ch_layout; ///< output channel layout
const uint32_t _in_ch_count; ///< input channel count
const uint32_t _out_ch_count; ///< output channel count
const float _surround_mix_level = C_30DB; ///< surround mixing level
const float _center_mix_level = C_30DB; ///< center mixing level
const float _lfe_mix_level = 1; ///< LFE mixing level
double _matrix[CHANNELS_MAX][CHANNELS_MAX] = {
{0}}; ///< floating point rematrixing coefficients
float _matrix_flt[CHANNELS_MAX][CHANNELS_MAX] = {
{0}}; ///< single precision floating point rematrixing coefficients
int32_t _matrix32[CHANNELS_MAX][CHANNELS_MAX] = {
{0}}; ///< 17.15 fixed point rematrixing coefficients
uint8_t _matrix_ch[CHANNELS_MAX][CHANNELS_MAX + 1] = {
{0}}; ///< Lists of input channels per output channel that have non zero
///< rematrixing coefficients
bool _clipping = false; ///< Set to true if clipping detection is required
bool _valid = false; ///< Set to true if context is valid.
};
int
MixerContext::auto_matrix()
{
double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS] = {{0}};
double maxcoef = 0;
float maxval;
cubeb_channel_layout in_ch_layout = clean_layout(_in_ch_layout);
cubeb_channel_layout out_ch_layout = clean_layout(_out_ch_layout);
if (!sane_layout(in_ch_layout)) {
// Channel Not Supported
LOG("Input Layout %x is not supported", _in_ch_layout);
return -1;
}
if (!sane_layout(out_ch_layout)) {
LOG("Output Layout %x is not supported", _out_ch_layout);
return -1;
}
for (uint32_t i = 0; i < FF_ARRAY_ELEMS(matrix); i++) {
if (in_ch_layout & out_ch_layout & (1U << i)) {
matrix[i][i] = 1.0;
}
}
cubeb_channel_layout unaccounted = in_ch_layout & ~out_ch_layout;
// Rematrixing is done via a matrix of coefficient that should be applied to
// all channels. Channels are treated as pair and must be symmetrical (if a
// left channel exists, the corresponding right should exist too) unless the
// output layout has similar layout. Channels are then mixed toward the front
// center or back center if they exist with a slight bias toward the front.
if (unaccounted & CHANNEL_FRONT_CENTER) {
if ((out_ch_layout & CUBEB_LAYOUT_STEREO) == CUBEB_LAYOUT_STEREO) {
if (in_ch_layout & CUBEB_LAYOUT_STEREO) {
matrix[FRONT_LEFT][FRONT_CENTER] += _center_mix_level;
matrix[FRONT_RIGHT][FRONT_CENTER] += _center_mix_level;
} else {
matrix[FRONT_LEFT][FRONT_CENTER] += M_SQRT1_2;
matrix[FRONT_RIGHT][FRONT_CENTER] += M_SQRT1_2;
}
}
}
if (unaccounted & CUBEB_LAYOUT_STEREO) {
if (out_ch_layout & CHANNEL_FRONT_CENTER) {
matrix[FRONT_CENTER][FRONT_LEFT] += M_SQRT1_2;
matrix[FRONT_CENTER][FRONT_RIGHT] += M_SQRT1_2;
if (in_ch_layout & CHANNEL_FRONT_CENTER)
matrix[FRONT_CENTER][FRONT_CENTER] = _center_mix_level * M_SQRT2;
}
}
if (unaccounted & CHANNEL_BACK_CENTER) {
if (out_ch_layout & CHANNEL_BACK_LEFT) {
matrix[BACK_LEFT][BACK_CENTER] += M_SQRT1_2;
matrix[BACK_RIGHT][BACK_CENTER] += M_SQRT1_2;
} else if (out_ch_layout & CHANNEL_SIDE_LEFT) {
matrix[SIDE_LEFT][BACK_CENTER] += M_SQRT1_2;
matrix[SIDE_RIGHT][BACK_CENTER] += M_SQRT1_2;
} else if (out_ch_layout & CHANNEL_FRONT_LEFT) {
matrix[FRONT_LEFT][BACK_CENTER] += _surround_mix_level * M_SQRT1_2;
matrix[FRONT_RIGHT][BACK_CENTER] += _surround_mix_level * M_SQRT1_2;
} else if (out_ch_layout & CHANNEL_FRONT_CENTER) {
matrix[FRONT_CENTER][BACK_CENTER] += _surround_mix_level * M_SQRT1_2;
}
}
if (unaccounted & CHANNEL_BACK_LEFT) {
if (out_ch_layout & CHANNEL_BACK_CENTER) {
matrix[BACK_CENTER][BACK_LEFT] += M_SQRT1_2;
matrix[BACK_CENTER][BACK_RIGHT] += M_SQRT1_2;
} else if (out_ch_layout & CHANNEL_SIDE_LEFT) {
if (in_ch_layout & CHANNEL_SIDE_LEFT) {
matrix[SIDE_LEFT][BACK_LEFT] += M_SQRT1_2;
matrix[SIDE_RIGHT][BACK_RIGHT] += M_SQRT1_2;
} else {
matrix[SIDE_LEFT][BACK_LEFT] += 1.0;
matrix[SIDE_RIGHT][BACK_RIGHT] += 1.0;
}
} else if (out_ch_layout & CHANNEL_FRONT_LEFT) {
matrix[FRONT_LEFT][BACK_LEFT] += _surround_mix_level;
matrix[FRONT_RIGHT][BACK_RIGHT] += _surround_mix_level;
} else if (out_ch_layout & CHANNEL_FRONT_CENTER) {
matrix[FRONT_CENTER][BACK_LEFT] += _surround_mix_level * M_SQRT1_2;
matrix[FRONT_CENTER][BACK_RIGHT] += _surround_mix_level * M_SQRT1_2;
}
}
if (unaccounted & CHANNEL_SIDE_LEFT) {
if (out_ch_layout & CHANNEL_BACK_LEFT) {
/* if back channels do not exist in the input, just copy side
channels to back channels, otherwise mix side into back */
if (in_ch_layout & CHANNEL_BACK_LEFT) {
matrix[BACK_LEFT][SIDE_LEFT] += M_SQRT1_2;
matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
} else {
matrix[BACK_LEFT][SIDE_LEFT] += 1.0;
matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
}
} else if (out_ch_layout & CHANNEL_BACK_CENTER) {
matrix[BACK_CENTER][SIDE_LEFT] += M_SQRT1_2;
matrix[BACK_CENTER][SIDE_RIGHT] += M_SQRT1_2;
} else if (out_ch_layout & CHANNEL_FRONT_LEFT) {
matrix[FRONT_LEFT][SIDE_LEFT] += _surround_mix_level;
matrix[FRONT_RIGHT][SIDE_RIGHT] += _surround_mix_level;
} else if (out_ch_layout & CHANNEL_FRONT_CENTER) {
matrix[FRONT_CENTER][SIDE_LEFT] += _surround_mix_level * M_SQRT1_2;
matrix[FRONT_CENTER][SIDE_RIGHT] += _surround_mix_level * M_SQRT1_2;
}
}
if (unaccounted & CHANNEL_FRONT_LEFT_OF_CENTER) {
if (out_ch_layout & CHANNEL_FRONT_LEFT) {
matrix[FRONT_LEFT][FRONT_LEFT_OF_CENTER] += 1.0;
matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER] += 1.0;
} else if (out_ch_layout & CHANNEL_FRONT_CENTER) {
matrix[FRONT_CENTER][FRONT_LEFT_OF_CENTER] += M_SQRT1_2;
matrix[FRONT_CENTER][FRONT_RIGHT_OF_CENTER] += M_SQRT1_2;
}
}
/* mix LFE into front left/right or center */
if (unaccounted & CHANNEL_LOW_FREQUENCY) {
if (out_ch_layout & CHANNEL_FRONT_CENTER) {
matrix[FRONT_CENTER][LOW_FREQUENCY] += _lfe_mix_level;
} else if (out_ch_layout & CHANNEL_FRONT_LEFT) {
matrix[FRONT_LEFT][LOW_FREQUENCY] += _lfe_mix_level * M_SQRT1_2;
matrix[FRONT_RIGHT][LOW_FREQUENCY] += _lfe_mix_level * M_SQRT1_2;
}
}
// Normalize the conversion matrix.
for (uint32_t out_i = 0, i = 0; i < CHANNELS_MAX; i++) {
double sum = 0;
int in_i = 0;
if ((out_ch_layout & (1U << i)) == 0) {
continue;
}
for (uint32_t j = 0; j < CHANNELS_MAX; j++) {
if ((in_ch_layout & (1U << j)) == 0) {
continue;
}
if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) {
_matrix[out_i][in_i] = matrix[i][j];
} else {
_matrix[out_i][in_i] =
i == j && (in_ch_layout & out_ch_layout & (1U << i));
}
sum += fabs(_matrix[out_i][in_i]);
in_i++;
}
maxcoef = std::max(maxcoef, sum);
out_i++;
}
if (_format == CUBEB_SAMPLE_S16NE) {
maxval = 1.0;
} else {
maxval = INT_MAX;
}
// Normalize matrix if needed.
if (maxcoef > maxval) {
maxcoef /= maxval;
for (uint32_t i = 0; i < CHANNELS_MAX; i++)
for (uint32_t j = 0; j < CHANNELS_MAX; j++) {
_matrix[i][j] /= maxcoef;
}
}
if (_format == CUBEB_SAMPLE_FLOAT32NE) {
for (uint32_t i = 0; i < FF_ARRAY_ELEMS(_matrix); i++) {
for (uint32_t j = 0; j < FF_ARRAY_ELEMS(_matrix[0]); j++) {
_matrix_flt[i][j] = _matrix[i][j];
}
}
}
return 0;
}
int
MixerContext::init()
{
int r = auto_matrix();
if (r) {
return r;
}
// Determine if matrix operation would overflow
if (_format == CUBEB_SAMPLE_S16NE) {
int maxsum = 0;
for (uint32_t i = 0; i < _out_ch_count; i++) {
double rem = 0;
int sum = 0;
for (uint32_t j = 0; j < _in_ch_count; j++) {
double target = _matrix[i][j] * 32768 + rem;
int value = lrintf(target);
rem += target - value;
sum += std::abs(value);
}
maxsum = std::max(maxsum, sum);
}
if (maxsum > 32768) {
_clipping = true;
}
}
// FIXME quantize for integers
for (uint32_t i = 0; i < CHANNELS_MAX; i++) {
int ch_in = 0;
for (uint32_t j = 0; j < CHANNELS_MAX; j++) {
_matrix32[i][j] = lrintf(_matrix[i][j] * 32768);
if (_matrix[i][j]) {
_matrix_ch[i][++ch_in] = j;
}
}
_matrix_ch[i][0] = ch_in;
}
return 0;
}
template <typename TYPE_SAMPLE, typename TYPE_COEFF, typename F>
void
sum2(TYPE_SAMPLE * out, uint32_t stride_out, const TYPE_SAMPLE * in1,
const TYPE_SAMPLE * in2, uint32_t stride_in, TYPE_COEFF coeff1,
TYPE_COEFF coeff2, F && operand, uint32_t frames)
{
static_assert(
std::is_same<TYPE_COEFF, decltype(operand(coeff1))>::value,
"function must return the same type as used by coeff1 and coeff2");
for (uint32_t i = 0; i < frames; i++) {
*out = operand(coeff1 * *in1 + coeff2 * *in2);
out += stride_out;
in1 += stride_in;
in2 += stride_in;
}
}
template <typename TYPE_SAMPLE, typename TYPE_COEFF, typename F>
void
copy(TYPE_SAMPLE * out, uint32_t stride_out, const TYPE_SAMPLE * in,
uint32_t stride_in, TYPE_COEFF coeff, F && operand, uint32_t frames)
{
static_assert(std::is_same<TYPE_COEFF, decltype(operand(coeff))>::value,
"function must return the same type as used by coeff");
for (uint32_t i = 0; i < frames; i++) {
*out = operand(coeff * *in);
out += stride_out;
in += stride_in;
}
}
template <typename TYPE, typename TYPE_COEFF, size_t COLS, typename F>
static int
rematrix(const MixerContext * s, TYPE * aOut, const TYPE * aIn,
const TYPE_COEFF (&matrix_coeff)[COLS][COLS], F && aF, uint32_t frames)
{
static_assert(
std::is_same<TYPE_COEFF, decltype(aF(matrix_coeff[0][0]))>::value,
"function must return the same type as used by matrix_coeff");
for (uint32_t out_i = 0; out_i < s->_out_ch_count; out_i++) {
TYPE * out = aOut + out_i;
switch (s->_matrix_ch[out_i][0]) {
case 0:
for (uint32_t i = 0; i < frames; i++) {
out[i * s->_out_ch_count] = 0;
}
break;
case 1: {
int in_i = s->_matrix_ch[out_i][1];
copy(out, s->_out_ch_count, aIn + in_i, s->_in_ch_count,
matrix_coeff[out_i][in_i], aF, frames);
} break;
case 2:
sum2(out, s->_out_ch_count, aIn + s->_matrix_ch[out_i][1],
aIn + s->_matrix_ch[out_i][2], s->_in_ch_count,
matrix_coeff[out_i][s->_matrix_ch[out_i][1]],
matrix_coeff[out_i][s->_matrix_ch[out_i][2]], aF, frames);
break;
default:
for (uint32_t i = 0; i < frames; i++) {
TYPE_COEFF v = 0;
for (uint32_t j = 0; j < s->_matrix_ch[out_i][0]; j++) {
uint32_t in_i = s->_matrix_ch[out_i][1 + j];
v += *(aIn + in_i + i * s->_in_ch_count) * matrix_coeff[out_i][in_i];
}
out[i * s->_out_ch_count] = aF(v);
}
break;
}
}
return 0;
}
struct cubeb_mixer {
cubeb_mixer(cubeb_sample_format format, uint32_t in_channels,
cubeb_channel_layout in_layout, uint32_t out_channels,
cubeb_channel_layout out_layout)
: _context(format, in_channels, in_layout, out_channels, out_layout)
{
}
template <typename T>
void copy_and_trunc(size_t frames, const T * input_buffer,
T * output_buffer) const
{
if (_context._in_ch_count <= _context._out_ch_count) {
// Not enough channels to copy, fill the gaps with silence.
if (_context._in_ch_count == 1 && _context._out_ch_count >= 2) {
// Special case for upmixing mono input to stereo and more. We will
// duplicate the mono channel to the first two channels. On most system,
// the first two channels are for left and right. It is commonly
// expected that mono will on both left+right channels
for (uint32_t i = 0; i < frames; i++) {
output_buffer[0] = output_buffer[1] = *input_buffer;
PodZero(output_buffer + 2, _context._out_ch_count - 2);
output_buffer += _context._out_ch_count;
input_buffer++;
}
return;
}
for (uint32_t i = 0; i < frames; i++) {
PodCopy(output_buffer, input_buffer, _context._in_ch_count);
output_buffer += _context._in_ch_count;
input_buffer += _context._in_ch_count;
PodZero(output_buffer, _context._out_ch_count - _context._in_ch_count);
output_buffer += _context._out_ch_count - _context._in_ch_count;
}
} else {
for (uint32_t i = 0; i < frames; i++) {
PodCopy(output_buffer, input_buffer, _context._out_ch_count);
output_buffer += _context._out_ch_count;
input_buffer += _context._in_ch_count;
}
}
}
int mix(size_t frames, const void * input_buffer, size_t input_buffer_size,
void * output_buffer, size_t output_buffer_size) const
{
if (frames <= 0 || _context._out_ch_count == 0) {
return 0;
}
// Check if output buffer is of sufficient size.
size_t size_read_needed =
frames * _context._in_ch_count * cubeb_sample_size(_context._format);
if (input_buffer_size < size_read_needed) {
// We don't have enough data to read!
return -1;
}
if (output_buffer_size * _context._in_ch_count <
size_read_needed * _context._out_ch_count) {
return -1;
}
if (!valid()) {
// The channel layouts were invalid or unsupported, instead we will simply
// either drop the extra channels, or fill with silence the missing ones
if (_context._format == CUBEB_SAMPLE_FLOAT32NE) {
copy_and_trunc(frames, static_cast<const float *>(input_buffer),
static_cast<float *>(output_buffer));
} else {
assert(_context._format == CUBEB_SAMPLE_S16NE);
copy_and_trunc(frames, static_cast<const int16_t *>(input_buffer),
reinterpret_cast<int16_t *>(output_buffer));
}
return 0;
}
switch (_context._format) {
case CUBEB_SAMPLE_FLOAT32NE: {
auto f = [](float x) { return x; };
return rematrix(&_context, static_cast<float *>(output_buffer),
static_cast<const float *>(input_buffer),
_context._matrix_flt, f, frames);
}
case CUBEB_SAMPLE_S16NE:
if (_context._clipping) {
auto f = [](int x) {
int y = (x + 16384) >> 15;
// clip the signed integer value into the -32768,32767 range.
if ((y + 0x8000U) & ~0xFFFF) {
return (y >> 31) ^ 0x7FFF;
}
return y;
};
return rematrix(&_context, static_cast<int16_t *>(output_buffer),
static_cast<const int16_t *>(input_buffer),
_context._matrix32, f, frames);
} else {
auto f = [](int x) { return (x + 16384) >> 15; };
return rematrix(&_context, static_cast<int16_t *>(output_buffer),
static_cast<const int16_t *>(input_buffer),
_context._matrix32, f, frames);
}
break;
default:
assert(false);
break;
}
return -1;
}
// Return false if any of the input or ouput layout were invalid.
bool valid() const { return _context._valid; }
virtual ~cubeb_mixer(){};
MixerContext _context;
};
cubeb_mixer *
cubeb_mixer_create(cubeb_sample_format format, uint32_t in_channels,
cubeb_channel_layout in_layout, uint32_t out_channels,
cubeb_channel_layout out_layout)
{
return new cubeb_mixer(format, in_channels, in_layout, out_channels,
out_layout);
}
void
cubeb_mixer_destroy(cubeb_mixer * mixer)
{
delete mixer;
}
int
cubeb_mixer_mix(cubeb_mixer * mixer, size_t frames, const void * input_buffer,
size_t input_buffer_size, void * output_buffer,
size_t output_buffer_size)
{
return mixer->mix(frames, input_buffer, input_buffer_size, output_buffer,
output_buffer_size);
}
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_MIXER
#define CUBEB_MIXER
#include "cubeb/cubeb.h" // for cubeb_channel_layout and cubeb_stream_params.
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct cubeb_mixer cubeb_mixer;
cubeb_mixer *
cubeb_mixer_create(cubeb_sample_format format, uint32_t in_channels,
cubeb_channel_layout in_layout, uint32_t out_channels,
cubeb_channel_layout out_layout);
void
cubeb_mixer_destroy(cubeb_mixer * mixer);
int
cubeb_mixer_mix(cubeb_mixer * mixer, size_t frames, const void * input_buffer,
size_t input_buffer_size, void * output_buffer,
size_t output_buffer_size);
unsigned int
cubeb_channel_layout_nb_channels(cubeb_channel_layout channel_layout);
#if defined(__cplusplus)
}
#endif
#endif // CUBEB_MIXER
+1797
View File
File diff suppressed because it is too large Load Diff
+1353
View File
File diff suppressed because it is too large Load Diff
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#include "cubeb_osx_run_loop.h"
#include "cubeb_log.h"
#include <AudioUnit/AudioUnit.h>
#include <CoreAudio/AudioHardware.h>
#include <CoreAudio/HostTime.h>
#include <CoreFoundation/CoreFoundation.h>
#include <cubeb/cubeb.h>
void
cubeb_set_coreaudio_notification_runloop()
{
/* This is needed so that AudioUnit listeners get called on this thread, and
* not the main thread. If we don't do that, they are not called, or a crash
* occur, depending on the OSX version. */
AudioObjectPropertyAddress runloop_address = {
kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster};
CFRunLoopRef run_loop = nullptr;
OSStatus r;
r = AudioObjectSetPropertyData(kAudioObjectSystemObject, &runloop_address, 0,
NULL, sizeof(CFRunLoopRef), &run_loop);
if (r != noErr) {
LOG("Could not make global CoreAudio notifications use their own thread.");
}
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright © 2014 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
/* On OSX 10.6 and after, the notification callbacks from the audio hardware are
* called on the main thread. Setting the kAudioHardwarePropertyRunLoop property
* to null tells the OSX to use a separate thread for that.
*
* This has to be called only once per process, so it is in a separate header
* for easy integration in other code bases. */
#if defined(__cplusplus)
extern "C" {
#endif
void
cubeb_set_coreaudio_notification_runloop();
#if defined(__cplusplus)
}
#endif
+1709
View File
File diff suppressed because it is too large Load Diff
+373
View File
@@ -0,0 +1,373 @@
/*
* Copyright © 2014 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef NOMINMAX
#define NOMINMAX
#endif // NOMINMAX
#include "cubeb_resampler.h"
#include "cubeb-speex-resampler.h"
#include "cubeb_resampler_internal.h"
#include "cubeb_utils.h"
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdio>
#include <cstring>
int
to_speex_quality(cubeb_resampler_quality q)
{
switch (q) {
case CUBEB_RESAMPLER_QUALITY_VOIP:
return SPEEX_RESAMPLER_QUALITY_VOIP;
case CUBEB_RESAMPLER_QUALITY_DEFAULT:
return SPEEX_RESAMPLER_QUALITY_DEFAULT;
case CUBEB_RESAMPLER_QUALITY_DESKTOP:
return SPEEX_RESAMPLER_QUALITY_DESKTOP;
default:
assert(false);
return 0XFFFFFFFF;
}
}
uint32_t
min_buffered_audio_frame(uint32_t sample_rate)
{
return sample_rate / 20;
}
template <typename T>
passthrough_resampler<T>::passthrough_resampler(cubeb_stream * s,
cubeb_data_callback cb,
void * ptr,
uint32_t input_channels,
uint32_t sample_rate)
: processor(input_channels), stream(s), data_callback(cb), user_ptr(ptr),
sample_rate(sample_rate)
{
}
template <typename T>
long
passthrough_resampler<T>::fill(void * input_buffer, long * input_frames_count,
void * output_buffer, long output_frames)
{
if (input_buffer) {
assert(input_frames_count);
}
assert((input_buffer && output_buffer) ||
(output_buffer && !input_buffer &&
(!input_frames_count || *input_frames_count == 0)) ||
(input_buffer && !output_buffer && output_frames == 0));
// When we have no pending input data and exactly as much input
// as output data, we don't need to copy it into the internal buffer
// and can directly forward it to the callback.
void * in_buf = input_buffer;
unsigned long pop_input_count = 0u;
if (input_buffer && !output_buffer) {
output_frames = *input_frames_count;
} else if (input_buffer) {
if (internal_input_buffer.length() != 0 ||
*input_frames_count < output_frames) {
// If we have pending input data left and have to first append the input
// so we can pass it as one pointer to the callback. Or this is a glitch.
// It can happen when system's performance is poor. Audible silence is
// being pushed at the end of the short input buffer. An improvement for
// the future is to resample to the output number of frames, when that
// happens.
internal_input_buffer.push(static_cast<T *>(input_buffer),
frames_to_samples(*input_frames_count));
if (internal_input_buffer.length() < frames_to_samples(output_frames)) {
// This is unxpected but it can happen when a glitch occurs. Fill the
// buffer with silence. First keep the actual number of input samples
// used without the silence.
pop_input_count = internal_input_buffer.length();
internal_input_buffer.push_silence(frames_to_samples(output_frames) -
internal_input_buffer.length());
} else {
pop_input_count = frames_to_samples(output_frames);
}
in_buf = internal_input_buffer.data();
} else if (*input_frames_count > output_frames) {
// In this case we have more input that we need output and
// fill the overflowing input into internal_input_buffer
// Since we have no other pending data, we can nonetheless
// pass the current input data directly to the callback
assert(pop_input_count == 0);
unsigned long samples_off = frames_to_samples(output_frames);
internal_input_buffer.push(
static_cast<T *>(input_buffer) + samples_off,
frames_to_samples(*input_frames_count - output_frames));
}
}
long rv =
data_callback(stream, user_ptr, in_buf, output_buffer, output_frames);
if (input_buffer) {
if (pop_input_count) {
internal_input_buffer.pop(nullptr, pop_input_count);
*input_frames_count = samples_to_frames(pop_input_count);
} else {
*input_frames_count = output_frames;
}
drop_audio_if_needed();
}
return rv;
}
// Explicit instantiation of template class.
template class passthrough_resampler<float>;
template class passthrough_resampler<short>;
template <typename T, typename InputProcessor, typename OutputProcessor>
cubeb_resampler_speex<T, InputProcessor, OutputProcessor>::
cubeb_resampler_speex(InputProcessor * input_processor,
OutputProcessor * output_processor, cubeb_stream * s,
cubeb_data_callback cb, void * ptr)
: input_processor(input_processor), output_processor(output_processor),
stream(s), data_callback(cb), user_ptr(ptr)
{
if (input_processor && output_processor) {
fill_internal = &cubeb_resampler_speex::fill_internal_duplex;
} else if (input_processor) {
fill_internal = &cubeb_resampler_speex::fill_internal_input;
} else if (output_processor) {
fill_internal = &cubeb_resampler_speex::fill_internal_output;
}
}
template <typename T, typename InputProcessor, typename OutputProcessor>
cubeb_resampler_speex<T, InputProcessor,
OutputProcessor>::~cubeb_resampler_speex()
{
}
template <typename T, typename InputProcessor, typename OutputProcessor>
long
cubeb_resampler_speex<T, InputProcessor, OutputProcessor>::fill(
void * input_buffer, long * input_frames_count, void * output_buffer,
long output_frames_needed)
{
/* Input and output buffers, typed */
T * in_buffer = reinterpret_cast<T *>(input_buffer);
T * out_buffer = reinterpret_cast<T *>(output_buffer);
return (this->*fill_internal)(in_buffer, input_frames_count, out_buffer,
output_frames_needed);
}
template <typename T, typename InputProcessor, typename OutputProcessor>
long
cubeb_resampler_speex<T, InputProcessor, OutputProcessor>::fill_internal_output(
T * input_buffer, long * input_frames_count, T * output_buffer,
long output_frames_needed)
{
assert(!input_buffer && (!input_frames_count || *input_frames_count == 0) &&
output_buffer && output_frames_needed);
if (!draining) {
long got = 0;
T * out_unprocessed = nullptr;
long output_frames_before_processing = 0;
/* fill directly the input buffer of the output processor to save a copy */
output_frames_before_processing =
output_processor->input_needed_for_output(output_frames_needed);
out_unprocessed =
output_processor->input_buffer(output_frames_before_processing);
got = data_callback(stream, user_ptr, nullptr, out_unprocessed,
output_frames_before_processing);
if (got < output_frames_before_processing) {
draining = true;
if (got < 0) {
return got;
}
}
output_processor->written(got);
}
/* Process the output. If not enough frames have been returned from the
* callback, drain the processors. */
return output_processor->output(output_buffer, output_frames_needed);
}
template <typename T, typename InputProcessor, typename OutputProcessor>
long
cubeb_resampler_speex<T, InputProcessor, OutputProcessor>::fill_internal_input(
T * input_buffer, long * input_frames_count, T * output_buffer,
long /*output_frames_needed*/)
{
assert(input_buffer && input_frames_count && *input_frames_count &&
!output_buffer);
/* The input data, after eventual resampling. This is passed to the callback.
*/
T * resampled_input = nullptr;
uint32_t resampled_frame_count =
input_processor->output_for_input(*input_frames_count);
/* process the input, and present exactly `output_frames_needed` in the
* callback. */
input_processor->input(input_buffer, *input_frames_count);
/* resampled_frame_count == 0 happens if the resampler
* doesn't have enough input frames buffered to produce 1 resampled frame. */
if (resampled_frame_count == 0) {
return *input_frames_count;
}
size_t frames_resampled = 0;
resampled_input =
input_processor->output(resampled_frame_count, &frames_resampled);
*input_frames_count = frames_resampled;
long got = data_callback(stream, user_ptr, resampled_input, nullptr,
resampled_frame_count);
/* Return the number of initial input frames or part of it.
* Since output_frames_needed == 0 in input scenario, the only
* available number outside resampler is the initial number of frames. */
return (*input_frames_count) * (got / resampled_frame_count);
}
template <typename T, typename InputProcessor, typename OutputProcessor>
long
cubeb_resampler_speex<T, InputProcessor, OutputProcessor>::fill_internal_duplex(
T * in_buffer, long * input_frames_count, T * out_buffer,
long output_frames_needed)
{
if (draining) {
// discard input and drain any signal remaining in the resampler.
return output_processor->output(out_buffer, output_frames_needed);
}
/* The input data, after eventual resampling. This is passed to the callback.
*/
T * resampled_input = nullptr;
/* The output buffer passed down in the callback, that might be resampled. */
T * out_unprocessed = nullptr;
long output_frames_before_processing = 0;
/* The number of frames returned from the callback. */
long got = 0;
/* We need to determine how much frames to present to the consumer.
* - If we have a two way stream, but we're only resampling input, we resample
* the input to the number of output frames.
* - If we have a two way stream, but we're only resampling the output, we
* resize the input buffer of the output resampler to the number of input
* frames, and we resample it afterwards.
* - If we resample both ways, we resample the input to the number of frames
* we would need to pass down to the consumer (before resampling the output),
* get the output data, and resample it to the number of frames needed by the
* caller. */
output_frames_before_processing =
output_processor->input_needed_for_output(output_frames_needed);
/* fill directly the input buffer of the output processor to save a copy */
out_unprocessed =
output_processor->input_buffer(output_frames_before_processing);
if (in_buffer) {
/* process the input, and present exactly `output_frames_needed` in the
* callback. */
input_processor->input(in_buffer, *input_frames_count);
size_t frames_resampled = 0;
resampled_input = input_processor->output(output_frames_before_processing,
&frames_resampled);
*input_frames_count = frames_resampled;
} else {
resampled_input = nullptr;
}
got = data_callback(stream, user_ptr, resampled_input, out_unprocessed,
output_frames_before_processing);
if (got < output_frames_before_processing) {
draining = true;
if (got < 0) {
return got;
}
}
output_processor->written(got);
input_processor->drop_audio_if_needed();
/* Process the output. If not enough frames have been returned from the
* callback, drain the processors. */
got = output_processor->output(out_buffer, output_frames_needed);
output_processor->drop_audio_if_needed();
return got;
}
/* Resampler C API */
cubeb_resampler *
cubeb_resampler_create(cubeb_stream * stream,
cubeb_stream_params * input_params,
cubeb_stream_params * output_params,
unsigned int target_rate, cubeb_data_callback callback,
void * user_ptr, cubeb_resampler_quality quality,
cubeb_resampler_reclock reclock)
{
cubeb_sample_format format;
assert(input_params || output_params);
if (input_params) {
format = input_params->format;
} else {
format = output_params->format;
}
switch (format) {
case CUBEB_SAMPLE_S16NE:
return cubeb_resampler_create_internal<short>(
stream, input_params, output_params, target_rate, callback, user_ptr,
quality, reclock);
case CUBEB_SAMPLE_FLOAT32NE:
return cubeb_resampler_create_internal<float>(
stream, input_params, output_params, target_rate, callback, user_ptr,
quality, reclock);
default:
assert(false);
return nullptr;
}
}
long
cubeb_resampler_fill(cubeb_resampler * resampler, void * input_buffer,
long * input_frames_count, void * output_buffer,
long output_frames_needed)
{
return resampler->fill(input_buffer, input_frames_count, output_buffer,
output_frames_needed);
}
void
cubeb_resampler_destroy(cubeb_resampler * resampler)
{
delete resampler;
}
long
cubeb_resampler_latency(cubeb_resampler * resampler)
{
return resampler->latency();
}
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright © 2014 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_RESAMPLER_H
#define CUBEB_RESAMPLER_H
#include "cubeb/cubeb.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct cubeb_resampler cubeb_resampler;
typedef enum {
CUBEB_RESAMPLER_QUALITY_VOIP,
CUBEB_RESAMPLER_QUALITY_DEFAULT,
CUBEB_RESAMPLER_QUALITY_DESKTOP
} cubeb_resampler_quality;
typedef enum {
CUBEB_RESAMPLER_RECLOCK_NONE,
CUBEB_RESAMPLER_RECLOCK_INPUT
} cubeb_resampler_reclock;
/**
* Create a resampler to adapt the requested sample rate into something that
* is accepted by the audio backend.
* @param stream A cubeb_stream instance supplied to the data callback.
* @param input_params Used to calculate bytes per frame and buffer size for
* resampling of the input side of the stream. NULL if input should not be
* resampled.
* @param output_params Used to calculate bytes per frame and buffer size for
* resampling of the output side of the stream. NULL if output should not be
* resampled.
* @param target_rate The sampling rate after resampling for the input side of
* the stream, and/or the sampling rate prior to resampling of the output side
* of the stream.
* @param callback A callback to request data for resampling.
* @param user_ptr User data supplied to the data callback.
* @param quality Quality of the resampler.
* @retval A non-null pointer if success.
*/
cubeb_resampler *
cubeb_resampler_create(cubeb_stream * stream,
cubeb_stream_params * input_params,
cubeb_stream_params * output_params,
unsigned int target_rate, cubeb_data_callback callback,
void * user_ptr, cubeb_resampler_quality quality,
cubeb_resampler_reclock reclock);
/**
* Fill the buffer with frames acquired using the data callback. Resampling will
* happen if necessary.
* @param resampler A cubeb_resampler instance.
* @param input_buffer A buffer of input samples
* @param input_frame_count The size of the buffer. Returns the number of frames
* consumed.
* @param output_buffer The buffer to be filled.
* @param output_frames_needed Number of frames that should be produced.
* @retval Number of frames that are actually produced.
* @retval CUBEB_ERROR on error.
*/
long
cubeb_resampler_fill(cubeb_resampler * resampler, void * input_buffer,
long * input_frame_count, void * output_buffer,
long output_frames_needed);
/**
* Destroy a cubeb_resampler.
* @param resampler A cubeb_resampler instance.
*/
void
cubeb_resampler_destroy(cubeb_resampler * resampler);
/**
* Returns the latency, in frames, of the resampler.
* @param resampler A cubeb resampler instance.
* @retval The latency, in frames, induced by the resampler.
*/
long
cubeb_resampler_latency(cubeb_resampler * resampler);
#if defined(__cplusplus)
}
#endif
#endif /* CUBEB_RESAMPLER_H */
+591
View File
@@ -0,0 +1,591 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_RESAMPLER_INTERNAL)
#define CUBEB_RESAMPLER_INTERNAL
#include <algorithm>
#include <cassert>
#include <cmath>
#include <memory>
#ifdef CUBEB_GECKO_BUILD
#include "mozilla/UniquePtr.h"
// In libc++, symbols such as std::unique_ptr may be defined in std::__1.
// The _LIBCPP_BEGIN_NAMESPACE_STD and _LIBCPP_END_NAMESPACE_STD macros
// will expand to the correct namespace.
#ifdef _LIBCPP_BEGIN_NAMESPACE_STD
#define MOZ_BEGIN_STD_NAMESPACE _LIBCPP_BEGIN_NAMESPACE_STD
#define MOZ_END_STD_NAMESPACE _LIBCPP_END_NAMESPACE_STD
#else
#define MOZ_BEGIN_STD_NAMESPACE namespace std {
#define MOZ_END_STD_NAMESPACE }
#endif
MOZ_BEGIN_STD_NAMESPACE
using mozilla::DefaultDelete;
using mozilla::UniquePtr;
#define default_delete DefaultDelete
#define unique_ptr UniquePtr
MOZ_END_STD_NAMESPACE
#endif
#include "cubeb-speex-resampler.h"
#include "cubeb/cubeb.h"
#include "cubeb_log.h"
#include "cubeb_resampler.h"
#include "cubeb_utils.h"
#include <stdio.h>
/* This header file contains the internal C++ API of the resamplers, for
* testing. */
// When dropping audio input frames to prevent building
// an input delay, this function returns the number of frames
// to keep in the buffer.
// @parameter sample_rate The sample rate of the stream.
// @return A number of frames to keep.
uint32_t
min_buffered_audio_frame(uint32_t sample_rate);
int
to_speex_quality(cubeb_resampler_quality q);
struct cubeb_resampler {
virtual long fill(void * input_buffer, long * input_frames_count,
void * output_buffer, long frames_needed) = 0;
virtual long latency() = 0;
virtual ~cubeb_resampler() {}
};
/** Base class for processors. This is just used to share methods for now. */
class processor {
public:
explicit processor(uint32_t channels) : channels(channels) {}
protected:
size_t frames_to_samples(size_t frames) const { return frames * channels; }
size_t samples_to_frames(size_t samples) const
{
assert(!(samples % channels));
return samples / channels;
}
/** The number of channel of the audio buffers to be resampled. */
const uint32_t channels;
};
template <typename T>
class passthrough_resampler : public cubeb_resampler, public processor {
public:
passthrough_resampler(cubeb_stream * s, cubeb_data_callback cb, void * ptr,
uint32_t input_channels, uint32_t sample_rate);
virtual long fill(void * input_buffer, long * input_frames_count,
void * output_buffer, long output_frames);
virtual long latency() { return 0; }
void drop_audio_if_needed()
{
uint32_t to_keep = min_buffered_audio_frame(sample_rate);
uint32_t available = samples_to_frames(internal_input_buffer.length());
if (available > to_keep) {
ALOGV("Dropping %u frames", available - to_keep);
internal_input_buffer.pop(nullptr,
frames_to_samples(available - to_keep));
}
}
private:
cubeb_stream * const stream;
const cubeb_data_callback data_callback;
void * const user_ptr;
/* This allows to buffer some input to account for the fact that we buffer
* some inputs. */
auto_array<T> internal_input_buffer;
uint32_t sample_rate;
};
/** Bidirectional resampler, can resample an input and an output stream, or just
* an input stream or output stream. In this case a delay is inserted in the
* opposite direction to keep the streams synchronized. */
template <typename T, typename InputProcessing, typename OutputProcessing>
class cubeb_resampler_speex : public cubeb_resampler {
public:
cubeb_resampler_speex(InputProcessing * input_processor,
OutputProcessing * output_processor, cubeb_stream * s,
cubeb_data_callback cb, void * ptr);
virtual ~cubeb_resampler_speex();
virtual long fill(void * input_buffer, long * input_frames_count,
void * output_buffer, long output_frames_needed);
virtual long latency()
{
if (input_processor && output_processor) {
assert(input_processor->latency() == output_processor->latency());
return input_processor->latency();
} else if (input_processor) {
return input_processor->latency();
} else {
return output_processor->latency();
}
}
private:
typedef long (cubeb_resampler_speex::*processing_callback)(
T * input_buffer, long * input_frames_count, T * output_buffer,
long output_frames_needed);
long fill_internal_duplex(T * input_buffer, long * input_frames_count,
T * output_buffer, long output_frames_needed);
long fill_internal_input(T * input_buffer, long * input_frames_count,
T * output_buffer, long output_frames_needed);
long fill_internal_output(T * input_buffer, long * input_frames_count,
T * output_buffer, long output_frames_needed);
std::unique_ptr<InputProcessing> input_processor;
std::unique_ptr<OutputProcessing> output_processor;
processing_callback fill_internal;
cubeb_stream * const stream;
const cubeb_data_callback data_callback;
void * const user_ptr;
bool draining = false;
};
/** Handles one way of a (possibly) duplex resampler, working on interleaved
* audio buffers of type T. This class is designed so that the number of frames
* coming out of the resampler can be precisely controled. It manages its own
* input buffer, and can use the caller's output buffer, or allocate its own. */
template <typename T> class cubeb_resampler_speex_one_way : public processor {
public:
/** The sample type of this resampler, either 16-bit integers or 32-bit
* floats. */
typedef T sample_type;
/** Construct a resampler resampling from #source_rate to #target_rate, that
* can be arbitrary, strictly positive number.
* @parameter channels The number of channels this resampler will resample.
* @parameter source_rate The sample-rate of the audio input.
* @parameter target_rate The sample-rate of the audio output.
* @parameter quality A number between 0 (fast, low quality) and 10 (slow,
* high quality). */
cubeb_resampler_speex_one_way(uint32_t channels, uint32_t source_rate,
uint32_t target_rate, int quality)
: processor(channels),
resampling_ratio(static_cast<float>(source_rate) / target_rate),
source_rate(source_rate), additional_latency(0), leftover_samples(0)
{
int r;
speex_resampler =
speex_resampler_init(channels, source_rate, target_rate, quality, &r);
assert(r == RESAMPLER_ERR_SUCCESS && "resampler allocation failure");
uint32_t input_latency = speex_resampler_get_input_latency(speex_resampler);
const size_t LATENCY_SAMPLES = 8192;
T input_buffer[LATENCY_SAMPLES] = {};
T output_buffer[LATENCY_SAMPLES] = {};
uint32_t input_frame_count = input_latency;
uint32_t output_frame_count = LATENCY_SAMPLES;
assert(input_latency * channels <= LATENCY_SAMPLES);
speex_resample(input_buffer, &input_frame_count, output_buffer,
&output_frame_count);
}
/** Destructor, deallocate the resampler */
virtual ~cubeb_resampler_speex_one_way()
{
speex_resampler_destroy(speex_resampler);
}
/* Fill the resampler with `input_frame_count` frames. */
void input(T * input_buffer, size_t input_frame_count)
{
resampling_in_buffer.push(input_buffer,
frames_to_samples(input_frame_count));
}
/** Outputs exactly `output_frame_count` into `output_buffer`.
* `output_buffer` has to be at least `output_frame_count` long. */
size_t output(T * output_buffer, size_t output_frame_count)
{
uint32_t in_len = samples_to_frames(resampling_in_buffer.length());
uint32_t out_len = output_frame_count;
speex_resample(resampling_in_buffer.data(), &in_len, output_buffer,
&out_len);
/* This shifts back any unresampled samples to the beginning of the input
buffer. */
resampling_in_buffer.pop(nullptr, frames_to_samples(in_len));
return out_len;
}
size_t output_for_input(uint32_t input_frames)
{
return (size_t)floorf(
(input_frames + samples_to_frames(resampling_in_buffer.length())) /
resampling_ratio);
}
/** Returns a buffer containing exactly `output_frame_count` resampled frames.
* The consumer should not hold onto the pointer. */
T * output(size_t output_frame_count, size_t * input_frames_used)
{
if (resampling_out_buffer.capacity() <
frames_to_samples(output_frame_count)) {
resampling_out_buffer.reserve(frames_to_samples(output_frame_count));
}
uint32_t in_len = samples_to_frames(resampling_in_buffer.length());
uint32_t out_len = output_frame_count;
speex_resample(resampling_in_buffer.data(), &in_len,
resampling_out_buffer.data(), &out_len);
if (out_len < output_frame_count) {
LOGV("underrun during resampling: got %u frames, expected %zu",
(unsigned)out_len, output_frame_count);
// silence the rightmost part
T * data = resampling_out_buffer.data();
for (uint32_t i = frames_to_samples(out_len);
i < frames_to_samples(output_frame_count); i++) {
data[i] = 0;
}
}
/* This shifts back any unresampled samples to the beginning of the input
buffer. */
resampling_in_buffer.pop(nullptr, frames_to_samples(in_len));
*input_frames_used = in_len;
return resampling_out_buffer.data();
}
/** Get the latency of the resampler, in output frames. */
uint32_t latency() const
{
/* The documentation of the resampler talks about "samples" here, but it
* only consider a single channel here so it's the same number of frames. */
int latency = 0;
latency = speex_resampler_get_output_latency(speex_resampler) +
additional_latency;
assert(latency >= 0);
return latency;
}
/** Returns the number of frames to pass in the input of the resampler to have
* exactly `output_frame_count` resampled frames. This can return a number
* slightly bigger than what is strictly necessary, but it guaranteed that the
* number of output frames will be exactly equal. */
uint32_t input_needed_for_output(int32_t output_frame_count) const
{
assert(output_frame_count >= 0); // Check overflow
int32_t unresampled_frames_left =
samples_to_frames(resampling_in_buffer.length());
int32_t resampled_frames_left =
samples_to_frames(resampling_out_buffer.length());
float input_frames_needed =
(output_frame_count - unresampled_frames_left) * resampling_ratio -
resampled_frames_left;
if (input_frames_needed < 0) {
return 0;
}
return (uint32_t)ceilf(input_frames_needed);
}
/** Returns a pointer to the input buffer, that contains empty space for at
* least `frame_count` elements. This is useful so that consumer can directly
* write into the input buffer of the resampler. The pointer returned is
* adjusted so that leftover data are not overwritten.
*/
T * input_buffer(size_t frame_count)
{
leftover_samples = resampling_in_buffer.length();
resampling_in_buffer.reserve(leftover_samples +
frames_to_samples(frame_count));
return resampling_in_buffer.data() + leftover_samples;
}
/** This method works with `input_buffer`, and allows to inform the processor
how much frames have been written in the provided buffer. */
void written(size_t written_frames)
{
resampling_in_buffer.set_length(leftover_samples +
frames_to_samples(written_frames));
}
void drop_audio_if_needed()
{
// Keep at most 100ms buffered.
uint32_t available = samples_to_frames(resampling_in_buffer.length());
uint32_t to_keep = min_buffered_audio_frame(source_rate);
if (available > to_keep) {
ALOGV("Dropping %u frames", available - to_keep);
resampling_in_buffer.pop(nullptr, frames_to_samples(available - to_keep));
}
}
private:
/** Wrapper for the speex resampling functions to have a typed
* interface. */
void speex_resample(float * input_buffer, uint32_t * input_frame_count,
float * output_buffer, uint32_t * output_frame_count)
{
#ifndef NDEBUG
int rv;
rv =
#endif
speex_resampler_process_interleaved_float(
speex_resampler, input_buffer, input_frame_count, output_buffer,
output_frame_count);
assert(rv == RESAMPLER_ERR_SUCCESS);
}
void speex_resample(short * input_buffer, uint32_t * input_frame_count,
short * output_buffer, uint32_t * output_frame_count)
{
#ifndef NDEBUG
int rv;
rv =
#endif
speex_resampler_process_interleaved_int(
speex_resampler, input_buffer, input_frame_count, output_buffer,
output_frame_count);
assert(rv == RESAMPLER_ERR_SUCCESS);
}
/** The state for the speex resampler used internaly. */
SpeexResamplerState * speex_resampler;
/** Source rate / target rate. */
const float resampling_ratio;
const uint32_t source_rate;
/** Storage for the input frames, to be resampled. Also contains
* any unresampled frames after resampling. */
auto_array<T> resampling_in_buffer;
/* Storage for the resampled frames, to be passed back to the caller. */
auto_array<T> resampling_out_buffer;
/** Additional latency inserted into the pipeline for synchronisation. */
uint32_t additional_latency;
/** When `input_buffer` is called, this allows tracking the number of samples
that were in the buffer. */
uint32_t leftover_samples;
};
/** This class allows delaying an audio stream by `frames` frames. */
template <typename T> class delay_line : public processor {
public:
/** Constructor
* @parameter frames the number of frames of delay.
* @parameter channels the number of channels of this delay line.
* @parameter sample_rate sample-rate of the audio going through this delay
* line */
delay_line(uint32_t frames, uint32_t channels, uint32_t sample_rate)
: processor(channels), length(frames), leftover_samples(0),
sample_rate(sample_rate)
{
/* Fill the delay line with some silent frames to add latency. */
delay_input_buffer.push_silence(frames * channels);
}
/** Push some frames into the delay line.
* @parameter buffer the frames to push.
* @parameter frame_count the number of frames in #buffer. */
void input(T * buffer, uint32_t frame_count)
{
delay_input_buffer.push(buffer, frames_to_samples(frame_count));
}
/** Pop some frames from the internal buffer, into a internal output buffer.
* @parameter frames_needed the number of frames to be returned.
* @return a buffer containing the delayed frames. The consumer should not
* hold onto the pointer. */
T * output(uint32_t frames_needed, size_t * input_frames_used)
{
if (delay_output_buffer.capacity() < frames_to_samples(frames_needed)) {
delay_output_buffer.reserve(frames_to_samples(frames_needed));
}
delay_output_buffer.clear();
delay_output_buffer.push(delay_input_buffer.data(),
frames_to_samples(frames_needed));
delay_input_buffer.pop(nullptr, frames_to_samples(frames_needed));
*input_frames_used = frames_needed;
return delay_output_buffer.data();
}
/** Get a pointer to the first writable location in the input buffer>
* @parameter frames_needed the number of frames the user needs to write into
* the buffer.
* @returns a pointer to a location in the input buffer where #frames_needed
* can be writen. */
T * input_buffer(uint32_t frames_needed)
{
leftover_samples = delay_input_buffer.length();
delay_input_buffer.reserve(leftover_samples +
frames_to_samples(frames_needed));
return delay_input_buffer.data() + leftover_samples;
}
/** This method works with `input_buffer`, and allows to inform the processor
how much frames have been written in the provided buffer. */
void written(size_t frames_written)
{
delay_input_buffer.set_length(leftover_samples +
frames_to_samples(frames_written));
}
/** Drains the delay line, emptying the buffer.
* @parameter output_buffer the buffer in which the frames are written.
* @parameter frames_needed the maximum number of frames to write.
* @return the actual number of frames written. */
size_t output(T * output_buffer, uint32_t frames_needed)
{
uint32_t in_len = samples_to_frames(delay_input_buffer.length());
uint32_t out_len = frames_needed;
uint32_t to_pop = std::min(in_len, out_len);
delay_input_buffer.pop(output_buffer, frames_to_samples(to_pop));
return to_pop;
}
/** Returns the number of frames one needs to input into the delay line to get
* #frames_needed frames back.
* @parameter frames_needed the number of frames one want to write into the
* delay_line
* @returns the number of frames one will get. */
uint32_t input_needed_for_output(int32_t frames_needed) const
{
assert(frames_needed >= 0); // Check overflow
return frames_needed;
}
/** Returns the number of frames produces for `input_frames` frames in input
*/
size_t output_for_input(uint32_t input_frames) { return input_frames; }
/** The number of frames this delay line delays the stream by.
* @returns The number of frames of delay. */
size_t latency() { return length; }
void drop_audio_if_needed()
{
size_t available = samples_to_frames(delay_input_buffer.length());
uint32_t to_keep = min_buffered_audio_frame(sample_rate);
if (available > to_keep) {
ALOGV("Dropping %u frames", available - to_keep);
delay_input_buffer.pop(nullptr, frames_to_samples(available - to_keep));
}
}
private:
/** The length, in frames, of this delay line */
uint32_t length;
/** When `input_buffer` is called, this allows tracking the number of samples
that where in the buffer. */
uint32_t leftover_samples;
/** The input buffer, where the delay is applied. */
auto_array<T> delay_input_buffer;
/** The output buffer. This is only ever used if using the ::output with a
* single argument. */
auto_array<T> delay_output_buffer;
uint32_t sample_rate;
};
/** This sits behind the C API and is more typed. */
template <typename T>
cubeb_resampler *
cubeb_resampler_create_internal(cubeb_stream * stream,
cubeb_stream_params * input_params,
cubeb_stream_params * output_params,
unsigned int target_rate,
cubeb_data_callback callback, void * user_ptr,
cubeb_resampler_quality quality,
cubeb_resampler_reclock reclock)
{
std::unique_ptr<cubeb_resampler_speex_one_way<T>> input_resampler = nullptr;
std::unique_ptr<cubeb_resampler_speex_one_way<T>> output_resampler = nullptr;
std::unique_ptr<delay_line<T>> input_delay = nullptr;
std::unique_ptr<delay_line<T>> output_delay = nullptr;
assert((input_params || output_params) &&
"need at least one valid parameter pointer.");
/* All the streams we have have a sample rate that matches the target
sample rate, use a no-op resampler, that simply forwards the buffers to the
callback. */
if (((input_params && input_params->rate == target_rate) &&
(output_params && output_params->rate == target_rate)) ||
(input_params && !output_params && (input_params->rate == target_rate)) ||
(output_params && !input_params &&
(output_params->rate == target_rate))) {
LOG("Input and output sample-rate match, target rate of %dHz", target_rate);
return new passthrough_resampler<T>(
stream, callback, user_ptr, input_params ? input_params->channels : 0,
target_rate);
}
/* Determine if we need to resampler one or both directions, and create the
resamplers. */
if (output_params && (output_params->rate != target_rate)) {
output_resampler.reset(new cubeb_resampler_speex_one_way<T>(
output_params->channels, target_rate, output_params->rate,
to_speex_quality(quality)));
if (!output_resampler) {
return NULL;
}
}
if (input_params && (input_params->rate != target_rate)) {
input_resampler.reset(new cubeb_resampler_speex_one_way<T>(
input_params->channels, input_params->rate, target_rate,
to_speex_quality(quality)));
if (!input_resampler) {
return NULL;
}
}
/* If we resample only one direction but we have a duplex stream, insert a
* delay line with a length equal to the resampler latency of the
* other direction so that the streams are synchronized. */
if (input_resampler && !output_resampler && input_params && output_params) {
output_delay.reset(new delay_line<T>(input_resampler->latency(),
output_params->channels,
output_params->rate));
if (!output_delay) {
return NULL;
}
} else if (output_resampler && !input_resampler && input_params &&
output_params) {
input_delay.reset(new delay_line<T>(output_resampler->latency(),
input_params->channels,
output_params->rate));
if (!input_delay) {
return NULL;
}
}
if (input_resampler && output_resampler) {
LOG("Resampling input (%d) and output (%d) to target rate of %dHz",
input_params->rate, output_params->rate, target_rate);
return new cubeb_resampler_speex<T, cubeb_resampler_speex_one_way<T>,
cubeb_resampler_speex_one_way<T>>(
input_resampler.release(), output_resampler.release(), stream, callback,
user_ptr);
} else if (input_resampler) {
LOG("Resampling input (%d) to target and output rate of %dHz",
input_params->rate, target_rate);
return new cubeb_resampler_speex<T, cubeb_resampler_speex_one_way<T>,
delay_line<T>>(input_resampler.release(),
output_delay.release(),
stream, callback, user_ptr);
} else {
LOG("Resampling output (%dHz) to target and input rate of %dHz",
output_params->rate, target_rate);
return new cubeb_resampler_speex<T, delay_line<T>,
cubeb_resampler_speex_one_way<T>>(
input_delay.release(), output_resampler.release(), stream, callback,
user_ptr);
}
}
#endif /* CUBEB_RESAMPLER_INTERNAL */
+155
View File
@@ -0,0 +1,155 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_RING_ARRAY_H
#define CUBEB_RING_ARRAY_H
#include "cubeb_utils.h"
/** Ring array of pointers is used to hold buffers. In case that
asynchronous producer/consumer callbacks do not arrive in a
repeated order the ring array stores the buffers and fetch
them in the correct order. */
typedef struct {
AudioBuffer * buffer_array; /**< Array that hold pointers of the allocated
space for the buffers. */
unsigned int tail; /**< Index of the last element (first to deliver). */
unsigned int count; /**< Number of elements in the array. */
unsigned int capacity; /**< Total length of the array. */
} ring_array;
static int
single_audiobuffer_init(AudioBuffer * buffer, uint32_t bytesPerFrame,
uint32_t channelsPerFrame, uint32_t frames)
{
assert(buffer);
assert(bytesPerFrame > 0 && channelsPerFrame && frames > 0);
size_t size = bytesPerFrame * frames;
buffer->mData = operator new(size);
if (buffer->mData == NULL) {
return CUBEB_ERROR;
}
PodZero(static_cast<char *>(buffer->mData), size);
buffer->mNumberChannels = channelsPerFrame;
buffer->mDataByteSize = size;
return CUBEB_OK;
}
/** Initialize the ring array.
@param ra The ring_array pointer of allocated structure.
@retval 0 on success. */
int
ring_array_init(ring_array * ra, uint32_t capacity, uint32_t bytesPerFrame,
uint32_t channelsPerFrame, uint32_t framesPerBuffer)
{
assert(ra);
if (capacity == 0 || bytesPerFrame == 0 || channelsPerFrame == 0 ||
framesPerBuffer == 0) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
ra->capacity = capacity;
ra->tail = 0;
ra->count = 0;
ra->buffer_array = new AudioBuffer[ra->capacity];
PodZero(ra->buffer_array, ra->capacity);
if (ra->buffer_array == NULL) {
return CUBEB_ERROR;
}
for (unsigned int i = 0; i < ra->capacity; ++i) {
if (single_audiobuffer_init(&ra->buffer_array[i], bytesPerFrame,
channelsPerFrame,
framesPerBuffer) != CUBEB_OK) {
return CUBEB_ERROR;
}
}
return CUBEB_OK;
}
/** Destroy the ring array.
@param ra The ring_array pointer.*/
void
ring_array_destroy(ring_array * ra)
{
assert(ra);
if (ra->buffer_array == NULL) {
return;
}
for (unsigned int i = 0; i < ra->capacity; ++i) {
if (ra->buffer_array[i].mData) {
operator delete(ra->buffer_array[i].mData);
}
}
delete[] ra->buffer_array;
}
/** Get the allocated buffer to be stored with fresh data.
@param ra The ring_array pointer.
@retval Pointer of the allocated space to be stored with fresh data or NULL
if full. */
AudioBuffer *
ring_array_get_free_buffer(ring_array * ra)
{
assert(ra && ra->buffer_array);
assert(ra->buffer_array[0].mData != NULL);
if (ra->count == ra->capacity) {
return NULL;
}
assert(ra->count == 0 || (ra->tail + ra->count) % ra->capacity != ra->tail);
AudioBuffer * ret = &ra->buffer_array[(ra->tail + ra->count) % ra->capacity];
++ra->count;
assert(ra->count <= ra->capacity);
return ret;
}
/** Get the next available buffer with data.
@param ra The ring_array pointer.
@retval Pointer of the next in order data buffer or NULL if empty. */
AudioBuffer *
ring_array_get_data_buffer(ring_array * ra)
{
assert(ra && ra->buffer_array);
assert(ra->buffer_array[0].mData != NULL);
if (ra->count == 0) {
return NULL;
}
AudioBuffer * ret = &ra->buffer_array[ra->tail];
ra->tail = (ra->tail + 1) % ra->capacity;
assert(ra->tail < ra->capacity);
assert(ra->count > 0);
--ra->count;
return ret;
}
/** When array is empty get the first allocated buffer in the array.
@param ra The ring_array pointer.
@retval If arrays is empty, pointer of the allocated space else NULL. */
AudioBuffer *
ring_array_get_dummy_buffer(ring_array * ra)
{
assert(ra && ra->buffer_array);
assert(ra->capacity > 0);
if (ra->count > 0) {
return NULL;
}
return &ra->buffer_array[0];
}
#endif // CUBEB_RING_ARRAY_H
+468
View File
@@ -0,0 +1,468 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_RING_BUFFER_H
#define CUBEB_RING_BUFFER_H
#include "cubeb_utils.h"
#include <algorithm>
#include <atomic>
#include <cstdint>
#include <memory>
#include <thread>
/**
* Single producer single consumer lock-free and wait-free ring buffer.
*
* This data structure allows producing data from one thread, and consuming it
* on another thread, safely and without explicit synchronization. If used on
* two threads, this data structure uses atomics for thread safety. It is
* possible to disable the use of atomics at compile time and only use this data
* structure on one thread.
*
* The role for the producer and the consumer must be constant, i.e., the
* producer should always be on one thread and the consumer should always be on
* another thread.
*
* Some words about the inner workings of this class:
* - Capacity is fixed. Only one allocation is performed, in the constructor.
* When reading and writing, the return value of the method allows checking if
* the ring buffer is empty or full.
* - We always keep the read index at least one element ahead of the write
* index, so we can distinguish between an empty and a full ring buffer: an
* empty ring buffer is when the write index is at the same position as the
* read index. A full buffer is when the write index is exactly one position
* before the read index.
* - We synchronize updates to the read index after having read the data, and
* the write index after having written the data. This means that the each
* thread can only touch a portion of the buffer that is not touched by the
* other thread.
* - Callers are expected to provide buffers. When writing to the queue,
* elements are copied into the internal storage from the buffer passed in.
* When reading from the queue, the user is expected to provide a buffer.
* Because this is a ring buffer, data might not be contiguous in memory,
* providing an external buffer to copy into is an easy way to have linear
* data for further processing.
*/
template <typename T> class ring_buffer_base {
public:
/**
* Constructor for a ring buffer.
*
* This performs an allocation, but is the only allocation that will happen
* for the life time of a `ring_buffer_base`.
*
* @param capacity The maximum number of element this ring buffer will hold.
*/
ring_buffer_base(int capacity)
/* One more element to distinguish from empty and full buffer. */
: capacity_(capacity + 1)
{
assert(storage_capacity() < std::numeric_limits<int>::max() / 2 &&
"buffer too large for the type of index used.");
assert(capacity_ > 0);
data_.reset(new T[storage_capacity()]);
/* If this queue is using atomics, initializing those members as the last
* action in the constructor acts as a full barrier, and allow capacity() to
* be thread-safe. */
write_index_ = 0;
read_index_ = 0;
}
/**
* Push `count` zero or default constructed elements in the array.
*
* Only safely called on the producer thread.
*
* @param count The number of elements to enqueue.
* @return The number of element enqueued.
*/
int enqueue_default(int count) { return enqueue(nullptr, count); }
/**
* @brief Put an element in the queue
*
* Only safely called on the producer thread.
*
* @param element The element to put in the queue.
*
* @return 1 if the element was inserted, 0 otherwise.
*/
int enqueue(T & element) { return enqueue(&element, 1); }
/**
* Push `count` elements in the ring buffer.
*
* Only safely called on the producer thread.
*
* @param elements a pointer to a buffer containing at least `count` elements.
* If `elements` is nullptr, zero or default constructed elements are
* enqueued.
* @param count The number of elements to read from `elements`
* @return The number of elements successfully coped from `elements` and
* inserted into the ring buffer.
*/
int enqueue(T * elements, int count)
{
#ifndef NDEBUG
assert_correct_thread(producer_id);
#endif
int wr_idx = write_index_.load(std::memory_order_relaxed);
int rd_idx = read_index_.load(std::memory_order_acquire);
if (full_internal(rd_idx, wr_idx)) {
return 0;
}
int to_write = std::min(available_write_internal(rd_idx, wr_idx), count);
/* First part, from the write index to the end of the array. */
int first_part = std::min(storage_capacity() - wr_idx, to_write);
/* Second part, from the beginning of the array */
int second_part = to_write - first_part;
if (elements) {
Copy(data_.get() + wr_idx, elements, first_part);
Copy(data_.get(), elements + first_part, second_part);
} else {
ConstructDefault(data_.get() + wr_idx, first_part);
ConstructDefault(data_.get(), second_part);
}
write_index_.store(increment_index(wr_idx, to_write),
std::memory_order_release);
return to_write;
}
/**
* Retrieve at most `count` elements from the ring buffer, and copy them to
* `elements`, if non-null.
*
* Only safely called on the consumer side.
*
* @param elements A pointer to a buffer with space for at least `count`
* elements. If `elements` is `nullptr`, `count` element will be discarded.
* @param count The maximum number of elements to dequeue.
* @return The number of elements written to `elements`.
*/
int dequeue(T * elements, int count)
{
#ifndef NDEBUG
assert_correct_thread(consumer_id);
#endif
int rd_idx = read_index_.load(std::memory_order_relaxed);
int wr_idx = write_index_.load(std::memory_order_acquire);
if (empty_internal(rd_idx, wr_idx)) {
return 0;
}
int to_read = std::min(available_read_internal(rd_idx, wr_idx), count);
int first_part = std::min(storage_capacity() - rd_idx, to_read);
int second_part = to_read - first_part;
if (elements) {
Copy(elements, data_.get() + rd_idx, first_part);
Copy(elements + first_part, data_.get(), second_part);
}
read_index_.store(increment_index(rd_idx, to_read),
std::memory_order_release);
return to_read;
}
/**
* Get the number of available element for consuming.
*
* Only safely called on the consumer thread.
*
* @return The number of available elements for reading.
*/
int available_read() const
{
#ifndef NDEBUG
assert_correct_thread(consumer_id);
#endif
return available_read_internal(
read_index_.load(std::memory_order_relaxed),
write_index_.load(std::memory_order_acquire));
}
/**
* Get the number of available elements for consuming.
*
* Only safely called on the producer thread.
*
* @return The number of empty slots in the buffer, available for writing.
*/
int available_write() const
{
#ifndef NDEBUG
assert_correct_thread(producer_id);
#endif
return available_write_internal(
read_index_.load(std::memory_order_acquire),
write_index_.load(std::memory_order_relaxed));
}
/**
* Get the total capacity, for this ring buffer.
*
* Can be called safely on any thread.
*
* @return The maximum capacity of this ring buffer.
*/
int capacity() const { return storage_capacity() - 1; }
/**
* Reset the consumer and producer thread identifier, in case the thread are
* being changed. This has to be externally synchronized. This is no-op when
* asserts are disabled.
*/
void reset_thread_ids()
{
#ifndef NDEBUG
consumer_id = producer_id = std::thread::id();
#endif
}
private:
/** Return true if the ring buffer is empty.
*
* @param read_index the read index to consider
* @param write_index the write index to consider
* @return true if the ring buffer is empty, false otherwise.
**/
bool empty_internal(int read_index, int write_index) const
{
return write_index == read_index;
}
/** Return true if the ring buffer is full.
*
* This happens if the write index is exactly one element behind the read
* index.
*
* @param read_index the read index to consider
* @param write_index the write index to consider
* @return true if the ring buffer is full, false otherwise.
**/
bool full_internal(int read_index, int write_index) const
{
return (write_index + 1) % storage_capacity() == read_index;
}
/**
* Return the size of the storage. It is one more than the number of elements
* that can be stored in the buffer.
*
* @return the number of elements that can be stored in the buffer.
*/
int storage_capacity() const { return capacity_; }
/**
* Returns the number of elements available for reading.
*
* @return the number of available elements for reading.
*/
int available_read_internal(int read_index, int write_index) const
{
if (write_index >= read_index) {
return write_index - read_index;
} else {
return write_index + storage_capacity() - read_index;
}
}
/**
* Returns the number of empty elements, available for writing.
*
* @return the number of elements that can be written into the array.
*/
int available_write_internal(int read_index, int write_index) const
{
/* We substract one element here to always keep at least one sample
* free in the buffer, to distinguish between full and empty array. */
int rv = read_index - write_index - 1;
if (write_index >= read_index) {
rv += storage_capacity();
}
return rv;
}
/**
* Increments an index, wrapping it around the storage.
*
* @param index a reference to the index to increment.
* @param increment the number by which `index` is incremented.
* @return the new index.
*/
int increment_index(int index, int increment) const
{
assert(increment >= 0);
return (index + increment) % storage_capacity();
}
/**
* @brief This allows checking that enqueue (resp. dequeue) are always called
* by the right thread.
*
* @param id the id of the thread that has called the calling method first.
*/
#ifndef NDEBUG
static void assert_correct_thread(std::thread::id & id)
{
if (id == std::thread::id()) {
id = std::this_thread::get_id();
return;
}
assert(id == std::this_thread::get_id());
}
#endif
/** Index at which the oldest element is at, in samples. */
std::atomic<int> read_index_;
/** Index at which to write new elements. `write_index` is always at
* least one element ahead of `read_index_`. */
std::atomic<int> write_index_;
/** Maximum number of elements that can be stored in the ring buffer. */
const int capacity_;
/** Data storage */
std::unique_ptr<T[]> data_;
#ifndef NDEBUG
/** The id of the only thread that is allowed to read from the queue. */
mutable std::thread::id consumer_id;
/** The id of the only thread that is allowed to write from the queue. */
mutable std::thread::id producer_id;
#endif
};
/**
* Adapter for `ring_buffer_base` that exposes an interface in frames.
*/
template <typename T> class audio_ring_buffer_base {
public:
/**
* @brief Constructor.
*
* @param channel_count Number of channels.
* @param capacity_in_frames The capacity in frames.
*/
audio_ring_buffer_base(int channel_count, int capacity_in_frames)
: channel_count(channel_count),
ring_buffer(frames_to_samples(capacity_in_frames))
{
assert(channel_count > 0);
}
/**
* @brief Enqueue silence.
*
* Only safely called on the producer thread.
*
* @param frame_count The number of frames of silence to enqueue.
* @return The number of frames of silence actually written to the queue.
*/
int enqueue_default(int frame_count)
{
return samples_to_frames(
ring_buffer.enqueue(nullptr, frames_to_samples(frame_count)));
}
/**
* @brief Enqueue `frames_count` frames of audio.
*
* Only safely called from the producer thread.
*
* @param [in] frames If non-null, the frames to enqueue.
* Otherwise, silent frames are enqueued.
* @param frame_count The number of frames to enqueue.
*
* @return The number of frames enqueued
*/
int enqueue(T * frames, int frame_count)
{
return samples_to_frames(
ring_buffer.enqueue(frames, frames_to_samples(frame_count)));
}
/**
* @brief Removes `frame_count` frames from the buffer, and
* write them to `frames` if it is non-null.
*
* Only safely called on the consumer thread.
*
* @param frames If non-null, the frames are copied to `frames`.
* Otherwise, they are dropped.
* @param frame_count The number of frames to remove.
*
* @return The number of frames actually dequeud.
*/
int dequeue(T * frames, int frame_count)
{
return samples_to_frames(
ring_buffer.dequeue(frames, frames_to_samples(frame_count)));
}
/**
* Get the number of available frames of audio for consuming.
*
* Only safely called on the consumer thread.
*
* @return The number of available frames of audio for reading.
*/
int available_read() const
{
return samples_to_frames(ring_buffer.available_read());
}
/**
* Get the number of available frames of audio for consuming.
*
* Only safely called on the producer thread.
*
* @return The number of empty slots in the buffer, available for writing.
*/
int available_write() const
{
return samples_to_frames(ring_buffer.available_write());
}
/**
* Get the total capacity, for this ring buffer.
*
* Can be called safely on any thread.
*
* @return The maximum capacity of this ring buffer.
*/
int capacity() const { return samples_to_frames(ring_buffer.capacity()); }
private:
/**
* @brief Frames to samples conversion.
*
* @param frames The number of frames.
*
* @return A number of samples.
*/
int frames_to_samples(int frames) const { return frames * channel_count; }
/**
* @brief Samples to frames conversion.
*
* @param samples The number of samples.
*
* @return A number of frames.
*/
int samples_to_frames(int samples) const { return samples / channel_count; }
/** Number of channels of audio that will stream through this ring buffer. */
int channel_count;
/** The underlying ring buffer that is used to store the data. */
ring_buffer_base<T> ring_buffer;
};
/**
* Lock-free instantiation of the `ring_buffer_base` type. This is safe to use
* from two threads, one producer, one consumer (that never change role),
* without explicit synchronization.
*/
template <typename T> using lock_free_queue = ring_buffer_base<T>;
/**
* Lock-free instantiation of the `audio_ring_buffer` type. This is safe to use
* from two threads, one producer, one consumer (that never change role),
* without explicit synchronization.
*/
template <typename T>
using lock_free_audio_ring_buffer = audio_ring_buffer_base<T>;
#endif // CUBEB_RING_BUFFER_H
+678
View File
@@ -0,0 +1,678 @@
/*
* Copyright (c) 2011 Alexandre Ratchov <alex@caoua.org>
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#include "cubeb-internal.h"
#include "cubeb/cubeb.h"
#include "cubeb_tracing.h"
#include <assert.h>
#include <dlfcn.h>
#include <inttypes.h>
#include <math.h>
#include <poll.h>
#include <pthread.h>
#include <sndio.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(CUBEB_SNDIO_DEBUG)
#define DPR(...) fprintf(stderr, __VA_ARGS__);
#else
#define DPR(...) \
do { \
} while (0)
#endif
#ifdef DISABLE_LIBSNDIO_DLOPEN
#define WRAP(x) x
#else
#define WRAP(x) (*cubeb_##x)
#define LIBSNDIO_API_VISIT(X) \
X(sio_close) \
X(sio_eof) \
X(sio_getpar) \
X(sio_initpar) \
X(sio_nfds) \
X(sio_onmove) \
X(sio_open) \
X(sio_pollfd) \
X(sio_read) \
X(sio_revents) \
X(sio_setpar) \
X(sio_start) \
X(sio_stop) \
X(sio_write)
#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
LIBSNDIO_API_VISIT(MAKE_TYPEDEF);
#undef MAKE_TYPEDEF
#endif
static struct cubeb_ops const sndio_ops;
struct cubeb {
struct cubeb_ops const * ops;
void * libsndio;
};
struct cubeb_stream {
/* Note: Must match cubeb_stream layout in cubeb.c. */
cubeb * context;
void * arg; /* user arg to {data,state}_cb */
/**/
pthread_t th; /* to run real-time audio i/o */
pthread_mutex_t mtx; /* protects hdl and pos */
struct sio_hdl * hdl; /* link us to sndio */
int mode; /* bitmap of SIO_{PLAY,REC} */
int active; /* cubec_start() called */
int conv; /* need float->s16 conversion */
unsigned char * rbuf; /* rec data consumed from here */
unsigned char * pbuf; /* play data is prepared here */
unsigned int nfr; /* number of frames in ibuf and obuf */
unsigned int rbpf; /* rec bytes per frame */
unsigned int pbpf; /* play bytes per frame */
unsigned int rchan; /* number of rec channels */
unsigned int pchan; /* number of play channels */
unsigned int nblks; /* number of blocks in the buffer */
uint64_t hwpos; /* frame number Joe hears right now */
uint64_t swpos; /* number of frames produced/consumed */
cubeb_data_callback data_cb; /* cb to preapare data */
cubeb_state_callback state_cb; /* cb to notify about state changes */
float volume; /* current volume */
};
static void
s16_setvol(void * ptr, long nsamp, float volume)
{
int16_t * dst = ptr;
int32_t mult = volume * 32768;
int32_t s;
while (nsamp-- > 0) {
s = *dst;
s = (s * mult) >> 15;
*(dst++) = s;
}
}
static void
float_to_s16(void * ptr, long nsamp, float volume)
{
int16_t * dst = ptr;
float * src = ptr;
float mult = volume * 32768;
int s;
while (nsamp-- > 0) {
s = lrintf(*(src++) * mult);
if (s < -32768)
s = -32768;
else if (s > 32767)
s = 32767;
*(dst++) = s;
}
}
static void
s16_to_float(void * ptr, long nsamp)
{
int16_t * src = ptr;
float * dst = ptr;
src += nsamp;
dst += nsamp;
while (nsamp-- > 0)
*(--dst) = (1. / 32768) * *(--src);
}
static const char *
sndio_get_device()
{
#ifdef __linux__
/*
* On other platforms default to sndio devices,
* so cubebs other backends can be used instead.
*/
const char * dev = getenv("AUDIODEVICE");
if (dev == NULL || *dev == '\0')
return "snd/0";
return dev;
#else
return SIO_DEVANY;
#endif
}
static void
sndio_onmove(void * arg, int delta)
{
cubeb_stream * s = (cubeb_stream *)arg;
s->hwpos += delta;
}
static void *
sndio_mainloop(void * arg)
{
struct pollfd * pfds;
cubeb_stream * s = arg;
int n, eof = 0, prime, nfds, events, revents, state = CUBEB_STATE_STARTED;
size_t pstart = 0, pend = 0, rstart = 0, rend = 0;
long nfr;
CUBEB_REGISTER_THREAD("cubeb rendering thread");
nfds = WRAP(sio_nfds)(s->hdl);
pfds = calloc(nfds, sizeof(struct pollfd));
if (pfds == NULL) {
CUBEB_UNREGISTER_THREAD();
return NULL;
}
DPR("sndio_mainloop()\n");
s->state_cb(s, s->arg, CUBEB_STATE_STARTED);
pthread_mutex_lock(&s->mtx);
if (!WRAP(sio_start)(s->hdl)) {
pthread_mutex_unlock(&s->mtx);
free(pfds);
CUBEB_UNREGISTER_THREAD();
return NULL;
}
DPR("sndio_mainloop(), started\n");
if (s->mode & SIO_PLAY) {
pstart = pend = s->nfr * s->pbpf;
prime = s->nblks;
if (s->mode & SIO_REC) {
memset(s->rbuf, 0, s->nfr * s->rbpf);
rstart = rend = s->nfr * s->rbpf;
}
} else {
prime = 0;
rstart = 0;
rend = s->nfr * s->rbpf;
}
for (;;) {
if (!s->active) {
DPR("sndio_mainloop() stopped\n");
state = CUBEB_STATE_STOPPED;
break;
}
/* do we have a complete block? */
if ((!(s->mode & SIO_PLAY) || pstart == pend) &&
(!(s->mode & SIO_REC) || rstart == rend)) {
if (eof) {
DPR("sndio_mainloop() drained\n");
state = CUBEB_STATE_DRAINED;
break;
}
if ((s->mode & SIO_REC) && s->conv)
s16_to_float(s->rbuf, s->nfr * s->rchan);
/* invoke call-back, it returns less that s->nfr if done */
pthread_mutex_unlock(&s->mtx);
nfr = s->data_cb(s, s->arg, s->rbuf, s->pbuf, s->nfr);
pthread_mutex_lock(&s->mtx);
if (nfr < 0) {
DPR("sndio_mainloop() cb err\n");
state = CUBEB_STATE_ERROR;
break;
}
s->swpos += nfr;
/* was this last call-back invocation (aka end-of-stream) ? */
if (nfr < s->nfr) {
if (!(s->mode & SIO_PLAY) || nfr == 0) {
state = CUBEB_STATE_DRAINED;
break;
}
/* need to write (aka drain) the partial play block we got */
pend = nfr * s->pbpf;
eof = 1;
}
if (prime > 0)
prime--;
if (s->mode & SIO_PLAY) {
if (s->conv)
float_to_s16(s->pbuf, nfr * s->pchan, s->volume);
else
s16_setvol(s->pbuf, nfr * s->pchan, s->volume);
}
if (s->mode & SIO_REC)
rstart = 0;
if (s->mode & SIO_PLAY)
pstart = 0;
}
events = 0;
if ((s->mode & SIO_REC) && rstart < rend && prime == 0)
events |= POLLIN;
if ((s->mode & SIO_PLAY) && pstart < pend)
events |= POLLOUT;
nfds = WRAP(sio_pollfd)(s->hdl, pfds, events);
if (nfds > 0) {
pthread_mutex_unlock(&s->mtx);
n = poll(pfds, nfds, -1);
pthread_mutex_lock(&s->mtx);
if (n < 0)
continue;
}
revents = WRAP(sio_revents)(s->hdl, pfds);
if (revents & POLLHUP) {
state = CUBEB_STATE_ERROR;
break;
}
if (revents & POLLOUT) {
n = WRAP(sio_write)(s->hdl, s->pbuf + pstart, pend - pstart);
if (n == 0 && WRAP(sio_eof)(s->hdl)) {
DPR("sndio_mainloop() werr\n");
state = CUBEB_STATE_ERROR;
break;
}
pstart += n;
}
if (revents & POLLIN) {
n = WRAP(sio_read)(s->hdl, s->rbuf + rstart, rend - rstart);
if (n == 0 && WRAP(sio_eof)(s->hdl)) {
DPR("sndio_mainloop() rerr\n");
state = CUBEB_STATE_ERROR;
break;
}
rstart += n;
}
/* skip rec block, if not recording (yet) */
if (prime > 0 && (s->mode & SIO_REC))
rstart = rend;
}
WRAP(sio_stop)(s->hdl);
s->hwpos = s->swpos;
pthread_mutex_unlock(&s->mtx);
s->state_cb(s, s->arg, state);
free(pfds);
CUBEB_UNREGISTER_THREAD();
return NULL;
}
/*static*/ int
sndio_init(cubeb ** context, char const * context_name)
{
void * libsndio = NULL;
struct sio_hdl * hdl;
assert(context);
#ifndef DISABLE_LIBSNDIO_DLOPEN
libsndio = dlopen("libsndio.so.7.0", RTLD_LAZY);
if (!libsndio) {
libsndio = dlopen("libsndio.so", RTLD_LAZY);
if (!libsndio) {
DPR("sndio_init(%s) failed dlopen(libsndio.so)\n", context_name);
return CUBEB_ERROR;
}
}
#define LOAD(x) \
{ \
cubeb_##x = dlsym(libsndio, #x); \
if (!cubeb_##x) { \
DPR("sndio_init(%s) failed dlsym(%s)\n", context_name, #x); \
dlclose(libsndio); \
return CUBEB_ERROR; \
} \
}
LIBSNDIO_API_VISIT(LOAD);
#undef LOAD
#endif
/* test if sndio works */
hdl = WRAP(sio_open)(sndio_get_device(), SIO_PLAY, 1);
if (hdl == NULL) {
return CUBEB_ERROR;
}
WRAP(sio_close)(hdl);
DPR("sndio_init(%s)\n", context_name);
*context = malloc(sizeof(**context));
if (*context == NULL)
return CUBEB_ERROR;
(*context)->libsndio = libsndio;
(*context)->ops = &sndio_ops;
(void)context_name;
return CUBEB_OK;
}
static char const *
sndio_get_backend_id(cubeb * context)
{
return "sndio";
}
static void
sndio_destroy(cubeb * context)
{
DPR("sndio_destroy()\n");
#ifndef DISABLE_LIBSNDIO_DLOPEN
if (context->libsndio)
dlclose(context->libsndio);
#endif
free(context);
}
static int
sndio_stream_init(cubeb * context, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
unsigned int latency_frames,
cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr)
{
cubeb_stream * s;
struct sio_par wpar, rpar;
cubeb_sample_format format;
int rate;
size_t bps;
DPR("sndio_stream_init(%s)\n", stream_name);
s = malloc(sizeof(cubeb_stream));
if (s == NULL)
return CUBEB_ERROR;
memset(s, 0, sizeof(cubeb_stream));
s->mode = 0;
if (input_stream_params) {
if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
DPR("sndio_stream_init(), loopback not supported\n");
goto err;
}
s->mode |= SIO_REC;
format = input_stream_params->format;
rate = input_stream_params->rate;
}
if (output_stream_params) {
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
DPR("sndio_stream_init(), loopback not supported\n");
goto err;
}
s->mode |= SIO_PLAY;
format = output_stream_params->format;
rate = output_stream_params->rate;
}
if (s->mode == 0) {
DPR("sndio_stream_init(), neither playing nor recording\n");
goto err;
}
s->context = context;
s->hdl = WRAP(sio_open)(sndio_get_device(), s->mode, 1);
if (s->hdl == NULL) {
DPR("sndio_stream_init(), sio_open() failed\n");
goto err;
}
WRAP(sio_initpar)(&wpar);
wpar.sig = 1;
wpar.bits = 16;
switch (format) {
case CUBEB_SAMPLE_S16LE:
wpar.le = 1;
break;
case CUBEB_SAMPLE_S16BE:
wpar.le = 0;
break;
case CUBEB_SAMPLE_FLOAT32NE:
wpar.le = SIO_LE_NATIVE;
break;
default:
DPR("sndio_stream_init() unsupported format\n");
goto err;
}
wpar.rate = rate;
if (s->mode & SIO_REC)
wpar.rchan = input_stream_params->channels;
if (s->mode & SIO_PLAY)
wpar.pchan = output_stream_params->channels;
wpar.appbufsz = latency_frames;
if (!WRAP(sio_setpar)(s->hdl, &wpar) || !WRAP(sio_getpar)(s->hdl, &rpar)) {
DPR("sndio_stream_init(), sio_setpar() failed\n");
goto err;
}
if (rpar.bits != wpar.bits || rpar.le != wpar.le || rpar.sig != wpar.sig ||
rpar.rate != wpar.rate ||
((s->mode & SIO_REC) && rpar.rchan != wpar.rchan) ||
((s->mode & SIO_PLAY) && rpar.pchan != wpar.pchan)) {
DPR("sndio_stream_init() unsupported params\n");
goto err;
}
WRAP(sio_onmove)(s->hdl, sndio_onmove, s);
s->active = 0;
s->nfr = rpar.round;
s->rbpf = rpar.bps * rpar.rchan;
s->pbpf = rpar.bps * rpar.pchan;
s->rchan = rpar.rchan;
s->pchan = rpar.pchan;
s->nblks = rpar.bufsz / rpar.round;
s->data_cb = data_callback;
s->state_cb = state_callback;
s->arg = user_ptr;
s->mtx = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
s->hwpos = s->swpos = 0;
if (format == CUBEB_SAMPLE_FLOAT32LE) {
s->conv = 1;
bps = sizeof(float);
} else {
s->conv = 0;
bps = rpar.bps;
}
if (s->mode & SIO_PLAY) {
s->pbuf = malloc(bps * rpar.pchan * rpar.round);
if (s->pbuf == NULL)
goto err;
}
if (s->mode & SIO_REC) {
s->rbuf = malloc(bps * rpar.rchan * rpar.round);
if (s->rbuf == NULL)
goto err;
}
s->volume = 1.;
*stream = s;
DPR("sndio_stream_init() end, ok\n");
(void)context;
(void)stream_name;
return CUBEB_OK;
err:
if (s->hdl)
WRAP(sio_close)(s->hdl);
if (s->pbuf)
free(s->pbuf);
if (s->rbuf)
free(s->pbuf);
free(s);
return CUBEB_ERROR;
}
static int
sndio_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
{
assert(ctx && max_channels);
*max_channels = 8;
return CUBEB_OK;
}
static int
sndio_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
{
/*
* We've no device-independent prefered rate; any rate will work if
* sndiod is running. If it isn't, 48kHz is what is most likely to
* work as most (but not all) devices support it.
*/
*rate = 48000;
return CUBEB_OK;
}
static int
sndio_get_min_latency(cubeb * ctx, cubeb_stream_params params,
uint32_t * latency_frames)
{
/*
* We've no device-independent minimum latency.
*/
*latency_frames = 2048;
return CUBEB_OK;
}
static void
sndio_stream_destroy(cubeb_stream * s)
{
DPR("sndio_stream_destroy()\n");
WRAP(sio_close)(s->hdl);
if (s->mode & SIO_PLAY)
free(s->pbuf);
if (s->mode & SIO_REC)
free(s->rbuf);
free(s);
}
static int
sndio_stream_start(cubeb_stream * s)
{
int err;
DPR("sndio_stream_start()\n");
s->active = 1;
err = pthread_create(&s->th, NULL, sndio_mainloop, s);
if (err) {
s->active = 0;
return CUBEB_ERROR;
}
return CUBEB_OK;
}
static int
sndio_stream_stop(cubeb_stream * s)
{
void * dummy;
DPR("sndio_stream_stop()\n");
if (s->active) {
s->active = 0;
pthread_join(s->th, &dummy);
}
return CUBEB_OK;
}
static int
sndio_stream_get_position(cubeb_stream * s, uint64_t * p)
{
pthread_mutex_lock(&s->mtx);
DPR("sndio_stream_get_position() %" PRId64 "\n", s->hwpos);
*p = s->hwpos;
pthread_mutex_unlock(&s->mtx);
return CUBEB_OK;
}
static int
sndio_stream_set_volume(cubeb_stream * s, float volume)
{
DPR("sndio_stream_set_volume(%f)\n", volume);
pthread_mutex_lock(&s->mtx);
if (volume < 0.)
volume = 0.;
else if (volume > 1.0)
volume = 1.;
s->volume = volume;
pthread_mutex_unlock(&s->mtx);
return CUBEB_OK;
}
int
sndio_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
{
// http://www.openbsd.org/cgi-bin/man.cgi?query=sio_open
// in the "Measuring the latency and buffers usage" paragraph.
*latency = stm->swpos - stm->hwpos;
return CUBEB_OK;
}
static int
sndio_enumerate_devices(cubeb * context, cubeb_device_type type,
cubeb_device_collection * collection)
{
static char dev[] = SIO_DEVANY;
cubeb_device_info * device;
device = malloc(sizeof(cubeb_device_info));
if (device == NULL)
return CUBEB_ERROR;
device->devid = dev; /* passed to stream_init() */
device->device_id = dev; /* printable in UI */
device->friendly_name = dev; /* same, but friendly */
device->group_id = dev; /* actual device if full-duplex */
device->vendor_name = NULL; /* may be NULL */
device->type = type; /* Input/Output */
device->state = CUBEB_DEVICE_STATE_ENABLED;
device->preferred = CUBEB_DEVICE_PREF_ALL;
device->format = CUBEB_DEVICE_FMT_S16NE;
device->default_format = CUBEB_DEVICE_FMT_S16NE;
device->max_channels = (type == CUBEB_DEVICE_TYPE_INPUT) ? 2 : 8;
device->default_rate = 48000;
device->min_rate = 4000;
device->max_rate = 192000;
device->latency_lo = 480;
device->latency_hi = 9600;
collection->device = device;
collection->count = 1;
return CUBEB_OK;
}
static int
sndio_device_collection_destroy(cubeb * context,
cubeb_device_collection * collection)
{
free(collection->device);
return CUBEB_OK;
}
static struct cubeb_ops const sndio_ops = {
.init = sndio_init,
.get_backend_id = sndio_get_backend_id,
.get_max_channel_count = sndio_get_max_channel_count,
.get_min_latency = sndio_get_min_latency,
.get_preferred_sample_rate = sndio_get_preferred_sample_rate,
.enumerate_devices = sndio_enumerate_devices,
.device_collection_destroy = sndio_device_collection_destroy,
.destroy = sndio_destroy,
.stream_init = sndio_stream_init,
.stream_destroy = sndio_stream_destroy,
.stream_start = sndio_stream_start,
.stream_stop = sndio_stream_stop,
.stream_get_position = sndio_stream_get_position,
.stream_get_latency = sndio_stream_get_latency,
.stream_set_volume = sndio_stream_set_volume,
.stream_set_name = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL};
+154
View File
@@ -0,0 +1,154 @@
/*
* Copyright © 2011 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#include "cubeb_strings.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define CUBEB_STRINGS_INLINE_COUNT 4
struct cubeb_strings {
uint32_t size;
uint32_t count;
char ** data;
char * small_store[CUBEB_STRINGS_INLINE_COUNT];
};
int
cubeb_strings_init(cubeb_strings ** strings)
{
cubeb_strings * strs = NULL;
if (!strings) {
return CUBEB_ERROR;
}
strs = calloc(1, sizeof(cubeb_strings));
assert(strs);
if (!strs) {
return CUBEB_ERROR;
}
strs->size = sizeof(strs->small_store) / sizeof(strs->small_store[0]);
strs->count = 0;
strs->data = strs->small_store;
*strings = strs;
return CUBEB_OK;
}
void
cubeb_strings_destroy(cubeb_strings * strings)
{
char ** sp = NULL;
char ** se = NULL;
if (!strings) {
return;
}
sp = strings->data;
se = sp + strings->count;
for (; sp != se; sp++) {
if (*sp) {
free(*sp);
}
}
if (strings->data != strings->small_store) {
free(strings->data);
}
free(strings);
}
/** Look for string in string storage.
@param strings Opaque pointer to interned string storage.
@param s String to look up.
@retval Read-only string or NULL if not found. */
static char const *
cubeb_strings_lookup(cubeb_strings * strings, char const * s)
{
char ** sp = NULL;
char ** se = NULL;
if (!strings || !s) {
return NULL;
}
sp = strings->data;
se = sp + strings->count;
for (; sp != se; sp++) {
if (*sp && strcmp(*sp, s) == 0) {
return *sp;
}
}
return NULL;
}
static char const *
cubeb_strings_push(cubeb_strings * strings, char const * s)
{
char * is = NULL;
if (strings->count == strings->size) {
char ** new_data;
uint32_t value_size = sizeof(char const *);
uint32_t new_size = strings->size * 2;
if (!new_size || value_size > (uint32_t)-1 / new_size) {
// overflow
return NULL;
}
if (strings->small_store == strings->data) {
// First time heap allocation.
new_data = malloc(new_size * value_size);
if (new_data) {
memcpy(new_data, strings->small_store, sizeof(strings->small_store));
}
} else {
new_data = realloc(strings->data, new_size * value_size);
}
if (!new_data) {
// out of memory
return NULL;
}
strings->size = new_size;
strings->data = new_data;
}
is = strdup(s);
strings->data[strings->count++] = is;
return is;
}
char const *
cubeb_strings_intern(cubeb_strings * strings, char const * s)
{
char const * is = NULL;
if (!strings || !s) {
return NULL;
}
is = cubeb_strings_lookup(strings, s);
if (is) {
return is;
}
return cubeb_strings_push(strings, s);
}
+47
View File
@@ -0,0 +1,47 @@
/*
* Copyright © 2011 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_STRINGS_H
#define CUBEB_STRINGS_H
#include "cubeb/cubeb.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** Opaque handle referencing interned string storage. */
typedef struct cubeb_strings cubeb_strings;
/** Initialize an interned string structure.
@param strings An out param where an opaque pointer to the
interned string storage will be returned.
@retval CUBEB_OK in case of success.
@retval CUBEB_ERROR in case of error. */
CUBEB_EXPORT int
cubeb_strings_init(cubeb_strings ** strings);
/** Destroy an interned string structure freeing all associated memory.
@param strings An opaque pointer to the interned string storage to
destroy. */
CUBEB_EXPORT void
cubeb_strings_destroy(cubeb_strings * strings);
/** Add string to internal storage.
@param strings Opaque pointer to interned string storage.
@param s String to add to storage.
@retval CUBEB_OK
@retval CUBEB_ERROR
*/
CUBEB_EXPORT char const *
cubeb_strings_intern(cubeb_strings * strings, char const * s);
#if defined(__cplusplus)
}
#endif
#endif // !CUBEB_STRINGS_H
+737
View File
@@ -0,0 +1,737 @@
/*
* Copyright © 2019-2020 Nia Alarie <nia@NetBSD.org>
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#include "cubeb-internal.h"
#include "cubeb/cubeb.h"
#include "cubeb_tracing.h"
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/audioio.h>
#include <sys/ioctl.h>
#include <unistd.h>
/* Default to 4 + 1 for the default device. */
#ifndef SUN_DEVICE_COUNT
#define SUN_DEVICE_COUNT (5)
#endif
/* Supported well by most hardware. */
#ifndef SUN_PREFER_RATE
#define SUN_PREFER_RATE (48000)
#endif
/* Standard acceptable minimum. */
#ifndef SUN_LATENCY_MS
#define SUN_LATENCY_MS (40)
#endif
#ifndef SUN_DEFAULT_DEVICE
#define SUN_DEFAULT_DEVICE "/dev/audio"
#endif
#ifndef SUN_BUFFER_FRAMES
#define SUN_BUFFER_FRAMES (32)
#endif
/*
* Supported on NetBSD regardless of hardware.
*/
#ifndef SUN_MAX_CHANNELS
#ifdef __NetBSD__
#define SUN_MAX_CHANNELS (12)
#else
#define SUN_MAX_CHANNELS (2)
#endif
#endif
#ifndef SUN_MIN_RATE
#define SUN_MIN_RATE (1000)
#endif
#ifndef SUN_MAX_RATE
#define SUN_MAX_RATE (192000)
#endif
static struct cubeb_ops const sun_ops;
struct cubeb {
struct cubeb_ops const * ops;
};
struct sun_stream {
char name[32];
int fd;
void * buf;
struct audio_info info;
unsigned frame_size; /* precision in bytes * channels */
bool floating;
};
struct cubeb_stream {
struct cubeb * context;
void * user_ptr;
pthread_t thread;
pthread_mutex_t mutex; /* protects running, volume, frames_written */
bool running;
float volume;
struct sun_stream play;
struct sun_stream record;
cubeb_data_callback data_cb;
cubeb_state_callback state_cb;
uint64_t frames_written;
uint64_t blocks_written;
};
int
sun_init(cubeb ** context, char const * context_name)
{
cubeb * c;
(void)context_name;
if ((c = calloc(1, sizeof(cubeb))) == NULL) {
return CUBEB_ERROR;
}
c->ops = &sun_ops;
*context = c;
return CUBEB_OK;
}
static void
sun_destroy(cubeb * context)
{
free(context);
}
static char const *
sun_get_backend_id(cubeb * context)
{
return "sun";
}
static int
sun_get_preferred_sample_rate(cubeb * context, uint32_t * rate)
{
(void)context;
*rate = SUN_PREFER_RATE;
return CUBEB_OK;
}
static int
sun_get_max_channel_count(cubeb * context, uint32_t * max_channels)
{
(void)context;
*max_channels = SUN_MAX_CHANNELS;
return CUBEB_OK;
}
static int
sun_get_min_latency(cubeb * context, cubeb_stream_params params,
uint32_t * latency_frames)
{
(void)context;
*latency_frames = SUN_LATENCY_MS * params.rate / 1000;
return CUBEB_OK;
}
static int
sun_get_hwinfo(const char * device, struct audio_info * format, int * props,
struct audio_device * dev)
{
int fd = -1;
if ((fd = open(device, O_RDONLY)) == -1) {
goto error;
}
#ifdef AUDIO_GETFORMAT
if (ioctl(fd, AUDIO_GETFORMAT, format) != 0) {
goto error;
}
#endif
#ifdef AUDIO_GETPROPS
if (ioctl(fd, AUDIO_GETPROPS, props) != 0) {
goto error;
}
#endif
if (ioctl(fd, AUDIO_GETDEV, dev) != 0) {
goto error;
}
close(fd);
return CUBEB_OK;
error:
if (fd != -1) {
close(fd);
}
return CUBEB_ERROR;
}
/*
* XXX: PR kern/54264
*/
static int
sun_prinfo_verify_sanity(struct audio_prinfo * prinfo)
{
return prinfo->precision >= 8 && prinfo->precision <= 32 &&
prinfo->channels >= 1 && prinfo->channels < SUN_MAX_CHANNELS &&
prinfo->sample_rate < SUN_MAX_RATE &&
prinfo->sample_rate > SUN_MIN_RATE;
}
static int
sun_enumerate_devices(cubeb * context, cubeb_device_type type,
cubeb_device_collection * collection)
{
unsigned i;
cubeb_device_info device = {0};
char dev[16] = SUN_DEFAULT_DEVICE;
char dev_friendly[64];
struct audio_info hwfmt;
struct audio_device hwname;
struct audio_prinfo * prinfo = NULL;
int hwprops;
collection->device = calloc(SUN_DEVICE_COUNT, sizeof(cubeb_device_info));
if (collection->device == NULL) {
return CUBEB_ERROR;
}
collection->count = 0;
for (i = 0; i < SUN_DEVICE_COUNT; ++i) {
if (i > 0) {
(void)snprintf(dev, sizeof(dev), "/dev/audio%u", i - 1);
}
if (sun_get_hwinfo(dev, &hwfmt, &hwprops, &hwname) != CUBEB_OK) {
continue;
}
#ifdef AUDIO_GETPROPS
device.type = 0;
if ((hwprops & AUDIO_PROP_CAPTURE) != 0 &&
sun_prinfo_verify_sanity(&hwfmt.record)) {
/* the device supports recording, probably */
device.type |= CUBEB_DEVICE_TYPE_INPUT;
}
if ((hwprops & AUDIO_PROP_PLAYBACK) != 0 &&
sun_prinfo_verify_sanity(&hwfmt.play)) {
/* the device supports playback, probably */
device.type |= CUBEB_DEVICE_TYPE_OUTPUT;
}
switch (device.type) {
case 0:
/* device doesn't do input or output, aliens probably involved */
continue;
case CUBEB_DEVICE_TYPE_INPUT:
if ((type & CUBEB_DEVICE_TYPE_INPUT) == 0) {
/* this device is input only, not scanning for those, skip it */
continue;
}
break;
case CUBEB_DEVICE_TYPE_OUTPUT:
if ((type & CUBEB_DEVICE_TYPE_OUTPUT) == 0) {
/* this device is output only, not scanning for those, skip it */
continue;
}
break;
}
if ((type & CUBEB_DEVICE_TYPE_INPUT) != 0) {
prinfo = &hwfmt.record;
}
if ((type & CUBEB_DEVICE_TYPE_OUTPUT) != 0) {
prinfo = &hwfmt.play;
}
#endif
if (i > 0) {
(void)snprintf(dev_friendly, sizeof(dev_friendly), "%s %s %s (%d)",
hwname.name, hwname.version, hwname.config, i - 1);
} else {
(void)snprintf(dev_friendly, sizeof(dev_friendly), "%s %s %s (default)",
hwname.name, hwname.version, hwname.config);
}
device.devid = (void *)(uintptr_t)i;
device.device_id = strdup(dev);
device.friendly_name = strdup(dev_friendly);
device.group_id = strdup(dev);
device.vendor_name = strdup(hwname.name);
device.type = type;
device.state = CUBEB_DEVICE_STATE_ENABLED;
device.preferred =
(i == 0) ? CUBEB_DEVICE_PREF_ALL : CUBEB_DEVICE_PREF_NONE;
#ifdef AUDIO_GETFORMAT
device.max_channels = prinfo->channels;
device.default_rate = prinfo->sample_rate;
#else
device.max_channels = 2;
device.default_rate = SUN_PREFER_RATE;
#endif
device.default_format = CUBEB_DEVICE_FMT_S16NE;
device.format = CUBEB_DEVICE_FMT_S16NE;
device.min_rate = SUN_MIN_RATE;
device.max_rate = SUN_MAX_RATE;
device.latency_lo = SUN_LATENCY_MS * SUN_MIN_RATE / 1000;
device.latency_hi = SUN_LATENCY_MS * SUN_MAX_RATE / 1000;
collection->device[collection->count++] = device;
}
return CUBEB_OK;
}
static int
sun_device_collection_destroy(cubeb * context,
cubeb_device_collection * collection)
{
unsigned i;
for (i = 0; i < collection->count; ++i) {
free((char *)collection->device[i].device_id);
free((char *)collection->device[i].friendly_name);
free((char *)collection->device[i].group_id);
free((char *)collection->device[i].vendor_name);
}
free(collection->device);
return CUBEB_OK;
}
static int
sun_copy_params(int fd, cubeb_stream * stream, cubeb_stream_params * params,
struct audio_info * info, struct audio_prinfo * prinfo)
{
prinfo->channels = params->channels;
prinfo->sample_rate = params->rate;
#ifdef AUDIO_ENCODING_SLINEAR_LE
switch (params->format) {
case CUBEB_SAMPLE_S16LE:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->precision = 16;
break;
case CUBEB_SAMPLE_S16BE:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->precision = 16;
break;
case CUBEB_SAMPLE_FLOAT32NE:
prinfo->encoding = AUDIO_ENCODING_SLINEAR;
prinfo->precision = 32;
break;
default:
LOG("Unsupported format");
return CUBEB_ERROR_INVALID_FORMAT;
}
#else
switch (params->format) {
case CUBEB_SAMPLE_S16NE:
prinfo->encoding = AUDIO_ENCODING_LINEAR;
prinfo->precision = 16;
break;
case CUBEB_SAMPLE_FLOAT32NE:
prinfo->encoding = AUDIO_ENCODING_LINEAR;
prinfo->precision = 32;
break;
default:
LOG("Unsupported format");
return CUBEB_ERROR_INVALID_FORMAT;
}
#endif
if (ioctl(fd, AUDIO_SETINFO, info) == -1) {
return CUBEB_ERROR;
}
if (ioctl(fd, AUDIO_GETINFO, info) == -1) {
return CUBEB_ERROR;
}
return CUBEB_OK;
}
static int
sun_stream_stop(cubeb_stream * s)
{
pthread_mutex_lock(&s->mutex);
if (s->running) {
s->running = false;
pthread_mutex_unlock(&s->mutex);
pthread_join(s->thread, NULL);
} else {
pthread_mutex_unlock(&s->mutex);
}
return CUBEB_OK;
}
static void
sun_stream_destroy(cubeb_stream * s)
{
sun_stream_stop(s);
pthread_mutex_destroy(&s->mutex);
if (s->play.fd != -1) {
close(s->play.fd);
}
if (s->record.fd != -1) {
close(s->record.fd);
}
free(s->play.buf);
free(s->record.buf);
free(s);
}
static void
sun_float_to_linear32(void * buf, unsigned sample_count, float vol)
{
float * in = buf;
int32_t * out = buf;
int32_t * tail = out + sample_count;
while (out < tail) {
float f = *(in++) * vol;
if (f < -1.0)
f = -1.0;
else if (f > 1.0)
f = 1.0;
*(out++) = f * (float)INT32_MAX;
}
}
static void
sun_linear32_to_float(void * buf, unsigned sample_count)
{
int32_t * in = buf;
float * out = buf;
float * tail = out + sample_count;
while (out < tail) {
*(out++) = (1.0 / 0x80000000) * *(in++);
}
}
static void
sun_linear16_set_vol(int16_t * buf, unsigned sample_count, float vol)
{
unsigned i;
int32_t multiplier = vol * 0x8000;
for (i = 0; i < sample_count; ++i) {
buf[i] = (buf[i] * multiplier) >> 15;
}
}
static void *
sun_io_routine(void * arg)
{
cubeb_stream * s = arg;
cubeb_state state = CUBEB_STATE_STARTED;
size_t to_read = 0;
long to_write = 0;
size_t write_ofs = 0;
size_t read_ofs = 0;
int drain = 0;
CUBEB_REGISTER_THREAD("cubeb rendering thread");
s->state_cb(s, s->user_ptr, CUBEB_STATE_STARTED);
while (state != CUBEB_STATE_ERROR) {
pthread_mutex_lock(&s->mutex);
if (!s->running) {
pthread_mutex_unlock(&s->mutex);
state = CUBEB_STATE_STOPPED;
break;
}
pthread_mutex_unlock(&s->mutex);
if (s->record.fd != -1 && s->record.floating) {
sun_linear32_to_float(s->record.buf,
s->record.info.record.channels * SUN_BUFFER_FRAMES);
}
to_write = s->data_cb(s, s->user_ptr, s->record.buf, s->play.buf,
SUN_BUFFER_FRAMES);
if (to_write == CUBEB_ERROR) {
state = CUBEB_STATE_ERROR;
break;
}
if (s->play.fd != -1) {
float vol;
pthread_mutex_lock(&s->mutex);
vol = s->volume;
pthread_mutex_unlock(&s->mutex);
if (s->play.floating) {
sun_float_to_linear32(s->play.buf,
s->play.info.play.channels * to_write, vol);
} else {
sun_linear16_set_vol(s->play.buf, s->play.info.play.channels * to_write,
vol);
}
}
if (to_write < SUN_BUFFER_FRAMES) {
drain = 1;
}
to_write = s->play.fd != -1 ? to_write : 0;
to_read = s->record.fd != -1 ? SUN_BUFFER_FRAMES : 0;
write_ofs = 0;
read_ofs = 0;
while (to_write > 0 || to_read > 0) {
size_t bytes;
ssize_t n, frames;
if (to_write > 0) {
bytes = to_write * s->play.frame_size;
if ((n = write(s->play.fd, (uint8_t *)s->play.buf + write_ofs, bytes)) <
0) {
state = CUBEB_STATE_ERROR;
break;
}
frames = n / s->play.frame_size;
pthread_mutex_lock(&s->mutex);
s->frames_written += frames;
pthread_mutex_unlock(&s->mutex);
to_write -= frames;
write_ofs += n;
}
if (to_read > 0) {
bytes = to_read * s->record.frame_size;
if ((n = read(s->record.fd, (uint8_t *)s->record.buf + read_ofs,
bytes)) < 0) {
state = CUBEB_STATE_ERROR;
break;
}
frames = n / s->record.frame_size;
to_read -= frames;
read_ofs += n;
}
}
if (drain && state != CUBEB_STATE_ERROR) {
state = CUBEB_STATE_DRAINED;
break;
}
}
s->state_cb(s, s->user_ptr, state);
CUBEB_UNREGISTER_THREAD();
return NULL;
}
static int
sun_stream_init(cubeb * context, cubeb_stream ** stream,
char const * stream_name, cubeb_devid input_device,
cubeb_stream_params * input_stream_params,
cubeb_devid output_device,
cubeb_stream_params * output_stream_params,
unsigned latency_frames, cubeb_data_callback data_callback,
cubeb_state_callback state_callback, void * user_ptr)
{
int ret = CUBEB_OK;
cubeb_stream * s = NULL;
(void)stream_name;
(void)latency_frames;
if ((s = calloc(1, sizeof(cubeb_stream))) == NULL) {
ret = CUBEB_ERROR;
goto error;
}
s->record.fd = -1;
s->play.fd = -1;
if (input_device != 0) {
snprintf(s->record.name, sizeof(s->record.name), "/dev/audio%zu",
(uintptr_t)input_device - 1);
} else {
snprintf(s->record.name, sizeof(s->record.name), "%s", SUN_DEFAULT_DEVICE);
}
if (output_device != 0) {
snprintf(s->play.name, sizeof(s->play.name), "/dev/audio%zu",
(uintptr_t)output_device - 1);
} else {
snprintf(s->play.name, sizeof(s->play.name), "%s", SUN_DEFAULT_DEVICE);
}
if (input_stream_params != NULL) {
if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
goto error;
}
if (s->record.fd == -1) {
if ((s->record.fd = open(s->record.name, O_RDONLY)) == -1) {
LOG("Audio device could not be opened as read-only");
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
}
AUDIO_INITINFO(&s->record.info);
#ifdef AUMODE_RECORD
s->record.info.mode = AUMODE_RECORD;
#endif
if ((ret = sun_copy_params(s->record.fd, s, input_stream_params,
&s->record.info, &s->record.info.record)) !=
CUBEB_OK) {
LOG("Setting record params failed");
goto error;
}
s->record.floating =
(input_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
}
if (output_stream_params != NULL) {
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
goto error;
}
if (s->play.fd == -1) {
if ((s->play.fd = open(s->play.name, O_WRONLY)) == -1) {
LOG("Audio device could not be opened as write-only");
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
}
AUDIO_INITINFO(&s->play.info);
#ifdef AUMODE_PLAY
s->play.info.mode = AUMODE_PLAY;
#endif
if ((ret = sun_copy_params(s->play.fd, s, output_stream_params,
&s->play.info, &s->play.info.play)) !=
CUBEB_OK) {
LOG("Setting play params failed");
goto error;
}
s->play.floating = (output_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
}
s->context = context;
s->volume = 1.0;
s->state_cb = state_callback;
s->data_cb = data_callback;
s->user_ptr = user_ptr;
if (pthread_mutex_init(&s->mutex, NULL) != 0) {
LOG("Failed to create mutex");
goto error;
}
s->play.frame_size =
s->play.info.play.channels * (s->play.info.play.precision / 8);
if (s->play.fd != -1 &&
(s->play.buf = calloc(SUN_BUFFER_FRAMES, s->play.frame_size)) == NULL) {
ret = CUBEB_ERROR;
goto error;
}
s->record.frame_size =
s->record.info.record.channels * (s->record.info.record.precision / 8);
if (s->record.fd != -1 &&
(s->record.buf = calloc(SUN_BUFFER_FRAMES, s->record.frame_size)) ==
NULL) {
ret = CUBEB_ERROR;
goto error;
}
*stream = s;
return CUBEB_OK;
error:
if (s != NULL) {
sun_stream_destroy(s);
}
return ret;
}
static int
sun_stream_start(cubeb_stream * s)
{
s->running = true;
if (pthread_create(&s->thread, NULL, sun_io_routine, s) != 0) {
LOG("Couldn't create thread");
return CUBEB_ERROR;
}
return CUBEB_OK;
}
static int
sun_stream_get_position(cubeb_stream * s, uint64_t * position)
{
#ifdef AUDIO_GETOOFFS
struct audio_offset offset;
if (ioctl(s->play.fd, AUDIO_GETOOFFS, &offset) == -1) {
return CUBEB_ERROR;
}
s->blocks_written += offset.deltablks;
*position = (s->blocks_written * s->play.info.blocksize) / s->play.frame_size;
return CUBEB_OK;
#else
pthread_mutex_lock(&s->mutex);
*position = s->frames_written;
pthread_mutex_unlock(&s->mutex);
return CUBEB_OK;
#endif
}
static int
sun_stream_get_latency(cubeb_stream * s, uint32_t * latency)
{
#ifdef AUDIO_GETBUFINFO
struct audio_info info;
if (ioctl(s->play.fd, AUDIO_GETBUFINFO, &info) == -1) {
return CUBEB_ERROR;
}
*latency = (info.play.seek + info.blocksize) / s->play.frame_size;
return CUBEB_OK;
#else
cubeb_stream_params params;
params.rate = s->play.info.play.sample_rate;
return sun_get_min_latency(NULL, params, latency);
#endif
}
static int
sun_stream_set_volume(cubeb_stream * stream, float volume)
{
pthread_mutex_lock(&stream->mutex);
stream->volume = volume;
pthread_mutex_unlock(&stream->mutex);
return CUBEB_OK;
}
static int
sun_get_current_device(cubeb_stream * stream, cubeb_device ** const device)
{
*device = calloc(1, sizeof(cubeb_device));
if (*device == NULL) {
return CUBEB_ERROR;
}
(*device)->input_name =
stream->record.fd != -1 ? strdup(stream->record.name) : NULL;
(*device)->output_name =
stream->play.fd != -1 ? strdup(stream->play.name) : NULL;
return CUBEB_OK;
}
static int
sun_stream_device_destroy(cubeb_stream * stream, cubeb_device * device)
{
(void)stream;
free(device->input_name);
free(device->output_name);
free(device);
return CUBEB_OK;
}
static struct cubeb_ops const sun_ops = {
.init = sun_init,
.get_backend_id = sun_get_backend_id,
.get_max_channel_count = sun_get_max_channel_count,
.get_min_latency = sun_get_min_latency,
.get_preferred_sample_rate = sun_get_preferred_sample_rate,
.enumerate_devices = sun_enumerate_devices,
.device_collection_destroy = sun_device_collection_destroy,
.destroy = sun_destroy,
.stream_init = sun_stream_init,
.stream_destroy = sun_stream_destroy,
.stream_start = sun_stream_start,
.stream_stop = sun_stream_stop,
.stream_get_position = sun_stream_get_position,
.stream_get_latency = sun_stream_get_latency,
.stream_get_input_latency = NULL,
.stream_set_volume = sun_stream_set_volume,
.stream_set_name = NULL,
.stream_get_current_device = sun_get_current_device,
.stream_device_destroy = sun_stream_device_destroy,
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL};
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright © 2022 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#ifndef CUBEB_TRACING_H
#define CUBEB_TRACING_H
/* Empty header to allow hooking up a frame profiler. */
// To be called once on a thread to register for tracing.
#define CUBEB_REGISTER_THREAD(name)
// To be called once before a registered threads exits.
#define CUBEB_UNREGISTER_THREAD()
// Insert a tracing marker, with a particular name.
// Phase can be 'x': instant marker, start time but no duration
// 'b': beginning of a marker with a duration
// 'e': end of a marker with a duration
#define CUBEB_TRACE(name, phase)
#endif // CUBEB_TRACING_H
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright © 2018 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#include "cubeb_utils.h"
size_t
cubeb_sample_size(cubeb_sample_format format)
{
switch (format) {
case CUBEB_SAMPLE_S16LE:
case CUBEB_SAMPLE_S16BE:
return sizeof(int16_t);
case CUBEB_SAMPLE_FLOAT32LE:
case CUBEB_SAMPLE_FLOAT32BE:
return sizeof(float);
default:
// should never happen as all cases are handled above.
assert(false);
return 0;
}
}
+309
View File
@@ -0,0 +1,309 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_UTILS)
#define CUBEB_UTILS
#include "cubeb/cubeb.h"
#ifdef __cplusplus
#include <assert.h>
#include <mutex>
#include <stdint.h>
#include <string.h>
#include <type_traits>
#if defined(_WIN32)
#include "cubeb_utils_win.h"
#else
#include "cubeb_utils_unix.h"
#endif
/** Similar to memcpy, but accounts for the size of an element. */
template <typename T>
void
PodCopy(T * destination, const T * source, size_t count)
{
static_assert(std::is_trivial<T>::value, "Requires trivial type");
assert(destination && source);
memcpy(destination, source, count * sizeof(T));
}
/** Similar to memmove, but accounts for the size of an element. */
template <typename T>
void
PodMove(T * destination, const T * source, size_t count)
{
static_assert(std::is_trivial<T>::value, "Requires trivial type");
assert(destination && source);
memmove(destination, source, count * sizeof(T));
}
/** Similar to a memset to zero, but accounts for the size of an element. */
template <typename T>
void
PodZero(T * destination, size_t count)
{
static_assert(std::is_trivial<T>::value, "Requires trivial type");
assert(destination);
memset(destination, 0, count * sizeof(T));
}
namespace {
template <typename T, typename Trait>
void
Copy(T * destination, const T * source, size_t count, Trait)
{
for (size_t i = 0; i < count; i++) {
destination[i] = source[i];
}
}
template <typename T>
void
Copy(T * destination, const T * source, size_t count, std::true_type)
{
PodCopy(destination, source, count);
}
} // namespace
/**
* This allows copying a number of elements from a `source` pointer to a
* `destination` pointer, using `memcpy` if it is safe to do so, or a loop that
* calls the constructors and destructors otherwise.
*/
template <typename T>
void
Copy(T * destination, const T * source, size_t count)
{
assert(destination && source);
Copy(destination, source, count, typename std::is_trivial<T>::type());
}
namespace {
template <typename T, typename Trait>
void
ConstructDefault(T * destination, size_t count, Trait)
{
for (size_t i = 0; i < count; i++) {
destination[i] = T();
}
}
template <typename T>
void
ConstructDefault(T * destination, size_t count, std::true_type)
{
PodZero(destination, count);
}
} // namespace
/**
* This allows zeroing (using memset) or default-constructing a number of
* elements calling the constructors and destructors if necessary.
*/
template <typename T>
void
ConstructDefault(T * destination, size_t count)
{
assert(destination);
ConstructDefault(destination, count, typename std::is_arithmetic<T>::type());
}
template <typename T> class auto_array {
public:
explicit auto_array(uint32_t capacity = 0)
: data_(capacity ? new T[capacity] : nullptr), capacity_(capacity),
length_(0)
{
}
~auto_array() { delete[] data_; }
/** Get a constant pointer to the underlying data. */
T * data() const { return data_; }
T * end() const { return data_ + length_; }
const T & at(size_t index) const
{
assert(index < length_ && "out of range");
return data_[index];
}
T & at(size_t index)
{
assert(index < length_ && "out of range");
return data_[index];
}
/** Get how much underlying storage this auto_array has. */
size_t capacity() const { return capacity_; }
/** Get how much elements this auto_array contains. */
size_t length() const { return length_; }
/** Keeps the storage, but removes all the elements from the array. */
void clear() { length_ = 0; }
/** Change the storage of this auto array, copying the elements to the new
* storage.
* @returns true in case of success
* @returns false if the new capacity is not big enough to accomodate for the
* elements in the array.
*/
bool reserve(size_t new_capacity)
{
if (new_capacity < length_) {
return false;
}
T * new_data = new T[new_capacity];
if (data_ && length_) {
PodCopy(new_data, data_, length_);
}
capacity_ = new_capacity;
delete[] data_;
data_ = new_data;
return true;
}
/** Append `length` elements to the end of the array, resizing the array if
* needed.
* @parameter elements the elements to append to the array.
* @parameter length the number of elements to append to the array.
*/
void push(const T * elements, size_t length)
{
if (length_ + length > capacity_) {
reserve(length_ + length);
}
PodCopy(data_ + length_, elements, length);
length_ += length;
}
/** Append `length` zero-ed elements to the end of the array, resizing the
* array if needed.
* @parameter length the number of elements to append to the array.
*/
void push_silence(size_t length)
{
if (length_ + length > capacity_) {
reserve(length + length_);
}
PodZero(data_ + length_, length);
length_ += length;
}
/** Prepend `length` zero-ed elements to the end of the array, resizing the
* array if needed.
* @parameter length the number of elements to prepend to the array.
*/
void push_front_silence(size_t length)
{
if (length_ + length > capacity_) {
reserve(length + length_);
}
PodMove(data_ + length, data_, length_);
PodZero(data_, length);
length_ += length;
}
/** Return the number of free elements in the array. */
size_t available() const { return capacity_ - length_; }
/** Copies `length` elements to `elements` if it is not null, and shift
* the remaining elements of the `auto_array` to the beginning.
* @parameter elements a buffer to copy the elements to, or nullptr.
* @parameter length the number of elements to copy.
* @returns true in case of success.
* @returns false if the auto_array contains less than `length` elements. */
bool pop(T * elements, size_t length)
{
if (length > length_) {
return false;
}
if (elements) {
PodCopy(elements, data_, length);
}
PodMove(data_, data_ + length, length_ - length);
length_ -= length;
return true;
}
void set_length(size_t length)
{
assert(length <= capacity_);
length_ = length;
}
private:
/** The underlying storage */
T * data_;
/** The size, in number of elements, of the storage. */
size_t capacity_;
/** The number of elements the array contains. */
size_t length_;
};
struct auto_array_wrapper {
virtual void push(void * elements, size_t length) = 0;
virtual size_t length() = 0;
virtual void push_silence(size_t length) = 0;
virtual bool pop(size_t length) = 0;
virtual void * data() = 0;
virtual void * end() = 0;
virtual void clear() = 0;
virtual bool reserve(size_t capacity) = 0;
virtual void set_length(size_t length) = 0;
virtual ~auto_array_wrapper() {}
};
template <typename T>
struct auto_array_wrapper_impl : public auto_array_wrapper {
auto_array_wrapper_impl() {}
explicit auto_array_wrapper_impl(uint32_t size) : ar(size) {}
void push(void * elements, size_t length) override
{
ar.push(static_cast<T *>(elements), length);
}
size_t length() override { return ar.length(); }
void push_silence(size_t length) override { ar.push_silence(length); }
bool pop(size_t length) override { return ar.pop(nullptr, length); }
void * data() override { return ar.data(); }
void * end() override { return ar.end(); }
void clear() override { ar.clear(); }
bool reserve(size_t capacity) override { return ar.reserve(capacity); }
void set_length(size_t length) override { ar.set_length(length); }
~auto_array_wrapper_impl() { ar.clear(); }
private:
auto_array<T> ar;
};
extern "C" {
size_t
cubeb_sample_size(cubeb_sample_format format);
}
using auto_lock = std::lock_guard<owned_critical_section>;
#endif // __cplusplus
#endif /* CUBEB_UTILS */
+88
View File
@@ -0,0 +1,88 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_UTILS_UNIX)
#define CUBEB_UTILS_UNIX
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
/* This wraps a critical section to track the owner in debug mode. */
class owned_critical_section {
public:
owned_critical_section()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#ifndef NDEBUG
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#else
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
#endif
#ifndef NDEBUG
int r =
#endif
pthread_mutex_init(&mutex, &attr);
#ifndef NDEBUG
assert(r == 0);
#endif
pthread_mutexattr_destroy(&attr);
}
~owned_critical_section()
{
#ifndef NDEBUG
int r =
#endif
pthread_mutex_destroy(&mutex);
#ifndef NDEBUG
assert(r == 0);
#endif
}
void lock()
{
#ifndef NDEBUG
int r =
#endif
pthread_mutex_lock(&mutex);
#ifndef NDEBUG
assert(r == 0 && "Deadlock");
#endif
}
void unlock()
{
#ifndef NDEBUG
int r =
#endif
pthread_mutex_unlock(&mutex);
#ifndef NDEBUG
assert(r == 0 && "Unlocking unlocked mutex");
#endif
}
void assert_current_thread_owns()
{
#ifndef NDEBUG
int r = pthread_mutex_lock(&mutex);
assert(r == EDEADLK);
#endif
}
private:
pthread_mutex_t mutex;
// Disallow copy and assignment because pthread_mutex_t cannot be copied.
owned_critical_section(const owned_critical_section &);
owned_critical_section & operator=(const owned_critical_section &);
};
#endif /* CUBEB_UTILS_UNIX */
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright © 2016 Mozilla Foundation
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
*/
#if !defined(CUBEB_UTILS_WIN)
#define CUBEB_UTILS_WIN
#include "cubeb-internal.h"
#include <windows.h>
/* This wraps an SRWLock to track the owner in debug mode, adapted from
NSPR and http://blogs.msdn.com/b/oldnewthing/archive/2013/07/12/10433554.aspx
*/
class owned_critical_section {
public:
owned_critical_section()
: srwlock(SRWLOCK_INIT)
#ifndef NDEBUG
,
owner(0)
#endif
{
}
void lock()
{
AcquireSRWLockExclusive(&srwlock);
#ifndef NDEBUG
XASSERT(owner != GetCurrentThreadId() && "recursive locking");
owner = GetCurrentThreadId();
#endif
}
void unlock()
{
#ifndef NDEBUG
/* GetCurrentThreadId cannot return 0: it is not a the valid thread id */
owner = 0;
#endif
ReleaseSRWLockExclusive(&srwlock);
}
/* This is guaranteed to have the good behaviour if it succeeds. The behaviour
is undefined otherwise. */
void assert_current_thread_owns()
{
#ifndef NDEBUG
/* This implies owner != 0, because GetCurrentThreadId cannot return 0. */
XASSERT(owner == GetCurrentThreadId());
#endif
}
private:
SRWLOCK srwlock;
#ifndef NDEBUG
DWORD owner;
#endif
// Disallow copy and assignment because SRWLock cannot be copied.
owned_critical_section(const owned_critical_section &);
owned_critical_section & operator=(const owned_critical_section &);
};
#endif /* CUBEB_UTILS_WIN */
File diff suppressed because it is too large Load Diff
+1171
View File
File diff suppressed because it is too large Load Diff
+235
View File
@@ -0,0 +1,235 @@
/* Copyright (C) 2003 Jean-Marc Valin */
/**
@file arch.h
@brief Various architecture definitions Speex
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCH_H
#define ARCH_H
/* A couple test to catch stupid option combinations */
#ifdef FIXED_POINT
#ifdef FLOATING_POINT
#error You cannot compile as floating point and fixed point at the same time
#endif
#ifdef _USE_SSE
#error SSE is only for floating-point
#endif
#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
#error Make up your mind. What CPU do you have?
#endif
#ifdef VORBIS_PSYCHO
#error Vorbis-psy model currently not implemented in fixed-point
#endif
#else
#ifndef FLOATING_POINT
#error You now need to define either FIXED_POINT or FLOATING_POINT
#endif
#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
#endif
#ifdef FIXED_POINT_DEBUG
#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
#endif
#endif
#ifndef OUTSIDE_SPEEX
#include "speex/speexdsp_types.h"
#endif
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
#ifdef FIXED_POINT
typedef spx_int16_t spx_word16_t;
typedef spx_int32_t spx_word32_t;
typedef spx_word32_t spx_mem_t;
typedef spx_word16_t spx_coef_t;
typedef spx_word16_t spx_lsp_t;
typedef spx_word32_t spx_sig_t;
#define Q15ONE 32767
#define LPC_SCALING 8192
#define SIG_SCALING 16384
#define LSP_SCALING 8192.
#define GAMMA_SCALING 32768.
#define GAIN_SCALING 64
#define GAIN_SCALING_1 0.015625
#define LPC_SHIFT 13
#define LSP_SHIFT 13
#define SIG_SHIFT 14
#define GAIN_SHIFT 6
#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))
#define VERY_SMALL 0
#define VERY_LARGE32 ((spx_word32_t)2147483647)
#define VERY_LARGE16 ((spx_word16_t)32767)
#define Q15_ONE ((spx_word16_t)32767)
#ifdef FIXED_DEBUG
#include "fixed_debug.h"
#else
#include "fixed_generic.h"
#ifdef ARM5E_ASM
#include "fixed_arm5e.h"
#elif defined (ARM4_ASM)
#include "fixed_arm4.h"
#elif defined (BFIN_ASM)
#include "fixed_bfin.h"
#endif
#endif
#else
typedef float spx_mem_t;
typedef float spx_coef_t;
typedef float spx_lsp_t;
typedef float spx_sig_t;
typedef float spx_word16_t;
typedef float spx_word32_t;
#define Q15ONE 1.0f
#define LPC_SCALING 1.f
#define SIG_SCALING 1.f
#define LSP_SCALING 1.f
#define GAMMA_SCALING 1.f
#define GAIN_SCALING 1.f
#define GAIN_SCALING_1 1.f
#define VERY_SMALL 1e-15f
#define VERY_LARGE32 1e15f
#define VERY_LARGE16 1e15f
#define Q15_ONE ((spx_word16_t)1.f)
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define EXTRACT16(x) (x)
#define EXTEND32(x) (x)
#define SHR16(a,shift) (a)
#define SHL16(a,shift) (a)
#define SHR32(a,shift) (a)
#define SHL32(a,shift) (a)
#define PSHR16(a,shift) (a)
#define PSHR32(a,shift) (a)
#define VSHR32(a,shift) (a)
#define SATURATE16(x,a) (x)
#define SATURATE32(x,a) (x)
#define SATURATE32PSHR(x,shift,a) (x)
#define PSHR(a,shift) (a)
#define SHR(a,shift) (a)
#define SHL(a,shift) (a)
#define SATURATE(x,a) (x)
#define ADD16(a,b) ((a)+(b))
#define SUB16(a,b) ((a)-(b))
#define ADD32(a,b) ((a)+(b))
#define SUB32(a,b) ((a)-(b))
#define MULT16_16_16(a,b) ((a)*(b))
#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b))
#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
#define MULT16_32_Q11(a,b) ((a)*(b))
#define MULT16_32_Q13(a,b) ((a)*(b))
#define MULT16_32_Q14(a,b) ((a)*(b))
#define MULT16_32_Q15(a,b) ((a)*(b))
#define MULT16_32_P15(a,b) ((a)*(b))
#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b))
#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b))
#define MAC16_16_P13(c,a,b) ((c)+(a)*(b))
#define MULT16_16_Q11_32(a,b) ((a)*(b))
#define MULT16_16_Q13(a,b) ((a)*(b))
#define MULT16_16_Q14(a,b) ((a)*(b))
#define MULT16_16_Q15(a,b) ((a)*(b))
#define MULT16_16_P15(a,b) ((a)*(b))
#define MULT16_16_P13(a,b) ((a)*(b))
#define MULT16_16_P14(a,b) ((a)*(b))
#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
#define WORD2INT(x) ((x) < -32767.5f ? -32768 : \
((x) > 32766.5f ? 32767 : (spx_int16_t)floor(.5 + (x))))
#endif
#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
/* 2 on TI C5x DSP */
#define BYTES_PER_CHAR 2
#define BITS_PER_CHAR 16
#define LOG2_BITS_PER_CHAR 4
#else
#define BYTES_PER_CHAR 1
#define BITS_PER_CHAR 8
#define LOG2_BITS_PER_CHAR 3
#endif
#ifdef FIXED_DEBUG
extern long long spx_mips;
#endif
#endif
+110
View File
@@ -0,0 +1,110 @@
/* Copyright (C) 2003 Jean-Marc Valin */
/**
@file fixed_generic.h
@brief Generic fixed-point operations
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_GENERIC_H
#define FIXED_GENERIC_H
#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define EXTRACT16(x) ((spx_word16_t)(x))
#define EXTEND32(x) ((spx_word32_t)(x))
#define SHR16(a,shift) ((a) >> (shift))
#define SHL16(a,shift) ((a) << (shift))
#define SHR32(a,shift) ((a) >> (shift))
#define SHL32(a,shift) ((a) << (shift))
#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
#define SATURATE32PSHR(x,shift,a) (((x)>=(SHL32(a,shift))) ? (a) : \
(x)<=-(SHL32(a,shift)) ? -(a) : \
(PSHR32(x, shift)))
#define SHR(a,shift) ((a) >> (shift))
#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))
#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))
#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))
#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))
/* result fits in 16 bits */
#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b))))
/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11)))
#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13)))
#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))
#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))
#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))
#endif
File diff suppressed because it is too large Load Diff
+201
View File
@@ -0,0 +1,201 @@
/* Copyright (C) 2007-2008 Jean-Marc Valin
* Copyright (C) 2008 Thorvald Natvig
* Copyright (C) 2011 Texas Instruments
* author Jyri Sarha
*/
/**
@file resample_neon.h
@brief Resampler functions (NEON version)
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <arm_neon.h>
#ifdef FIXED_POINT
#ifdef __thumb2__
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
int32_t ret;
asm ("ssat %[ret], #16, %[a]"
: [ret] "=&r" (ret)
: [a] "r" (a)
: );
return ret;
}
#else
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
int32_t ret;
asm ("vmov.s32 d0[0], %[a]\n"
"vqmovn.s32 d0, q0\n"
"vmov.s16 %[ret], d0[0]\n"
: [ret] "=&r" (ret)
: [a] "r" (a)
: "q0");
return ret;
}
#endif
#undef WORD2INT
#define WORD2INT(x) (saturate_32bit_to_16bit(x))
#define OVERRIDE_INNER_PRODUCT_SINGLE
/* Only works when len % 4 == 0 */
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
{
int32_t ret;
uint32_t remainder = len % 16;
len = len - remainder;
asm volatile (" cmp %[len], #0\n"
" bne 1f\n"
" vld1.16 {d16}, [%[b]]!\n"
" vld1.16 {d20}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmull.s16 q0, d16, d20\n"
" beq 5f\n"
" b 4f\n"
"1:"
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
" vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmull.s16 q0, d16, d20\n"
" vmlal.s16 q0, d17, d21\n"
" vmlal.s16 q0, d18, d22\n"
" vmlal.s16 q0, d19, d23\n"
" beq 3f\n"
"2:"
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
" vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmlal.s16 q0, d16, d20\n"
" vmlal.s16 q0, d17, d21\n"
" vmlal.s16 q0, d18, d22\n"
" vmlal.s16 q0, d19, d23\n"
" bne 2b\n"
"3:"
" cmp %[remainder], #0\n"
" beq 5f\n"
"4:"
" vld1.16 {d16}, [%[b]]!\n"
" vld1.16 {d20}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmlal.s16 q0, d16, d20\n"
" bne 4b\n"
"5:"
" vaddl.s32 q0, d0, d1\n"
" vadd.s64 d0, d0, d1\n"
" vqmovn.s64 d0, q0\n"
" vqrshrn.s32 d0, q0, #15\n"
" vmov.s16 %[ret], d0[0]\n"
: [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b),
[len] "+r" (len), [remainder] "+r" (remainder)
:
: "cc", "q0",
"d16", "d17", "d18", "d19",
"d20", "d21", "d22", "d23");
return ret;
}
#elif defined(FLOATING_POINT)
static inline int32_t saturate_float_to_16bit(float a) {
int32_t ret;
asm ("vmov.f32 d0[0], %[a]\n"
"vcvt.s32.f32 d0, d0, #15\n"
"vqrshrn.s32 d0, q0, #15\n"
"vmov.s16 %[ret], d0[0]\n"
: [ret] "=&r" (ret)
: [a] "r" (a)
: "q0");
return ret;
}
#undef WORD2INT
#define WORD2INT(x) (saturate_float_to_16bit(x))
#define OVERRIDE_INNER_PRODUCT_SINGLE
/* Only works when len % 4 == 0 */
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
{
float ret;
uint32_t remainder = len % 16;
len = len - remainder;
asm volatile (" cmp %[len], #0\n"
" bne 1f\n"
" vld1.32 {q4}, [%[b]]!\n"
" vld1.32 {q8}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmul.f32 q0, q4, q8\n"
" bne 4f\n"
" b 5f\n"
"1:"
" vld1.32 {q4, q5}, [%[b]]!\n"
" vld1.32 {q8, q9}, [%[a]]!\n"
" vld1.32 {q6, q7}, [%[b]]!\n"
" vld1.32 {q10, q11}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmul.f32 q0, q4, q8\n"
" vmul.f32 q1, q5, q9\n"
" vmul.f32 q2, q6, q10\n"
" vmul.f32 q3, q7, q11\n"
" beq 3f\n"
"2:"
" vld1.32 {q4, q5}, [%[b]]!\n"
" vld1.32 {q8, q9}, [%[a]]!\n"
" vld1.32 {q6, q7}, [%[b]]!\n"
" vld1.32 {q10, q11}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmla.f32 q0, q4, q8\n"
" vmla.f32 q1, q5, q9\n"
" vmla.f32 q2, q6, q10\n"
" vmla.f32 q3, q7, q11\n"
" bne 2b\n"
"3:"
" vadd.f32 q4, q0, q1\n"
" vadd.f32 q5, q2, q3\n"
" cmp %[remainder], #0\n"
" vadd.f32 q0, q4, q5\n"
" beq 5f\n"
"4:"
" vld1.32 {q6}, [%[b]]!\n"
" vld1.32 {q10}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmla.f32 q0, q6, q10\n"
" bne 4b\n"
"5:"
" vadd.f32 d0, d0, d1\n"
" vpadd.f32 d0, d0, d0\n"
" vmov.f32 %[ret], d0[0]\n"
: [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b),
[len] "+l" (len), [remainder] "+l" (remainder)
:
: "cc", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8",
"q9", "q10", "q11");
return ret;
}
#endif
+128
View File
@@ -0,0 +1,128 @@
/* Copyright (C) 2007-2008 Jean-Marc Valin
* Copyright (C) 2008 Thorvald Natvig
*/
/**
@file resample_sse.h
@brief Resampler functions (SSE version)
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <xmmintrin.h>
#define OVERRIDE_INNER_PRODUCT_SINGLE
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
{
int i;
float ret;
__m128 sum = _mm_setzero_ps();
for (i=0;i<len;i+=8)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
}
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
}
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
int i;
float ret;
__m128 sum = _mm_setzero_ps();
__m128 f = _mm_loadu_ps(frac);
for(i=0;i<len;i+=2)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
}
sum = _mm_mul_ps(f, sum);
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
}
#ifdef _USE_SSE2
#include <emmintrin.h>
#define OVERRIDE_INNER_PRODUCT_DOUBLE
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
{
int i;
double ret;
__m128d sum = _mm_setzero_pd();
__m128 t;
for (i=0;i<len;i+=8)
{
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
}
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
int i;
double ret;
__m128d sum;
__m128d sum1 = _mm_setzero_pd();
__m128d sum2 = _mm_setzero_pd();
__m128 f = _mm_loadu_ps(frac);
__m128d f1 = _mm_cvtps_pd(f);
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
__m128 t;
for(i=0;i<len;i+=2)
{
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum1 = _mm_mul_pd(f1, sum1);
sum2 = _mm_mul_pd(f2, sum2);
sum = _mm_add_pd(sum1, sum2);
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
}
#endif
+10
View File
@@ -0,0 +1,10 @@
#ifndef __SPEEX_TYPES_H__
#define __SPEEX_TYPES_H__
/* these are filled in by configure */
typedef int16_t spx_int16_t;
typedef uint16_t spx_uint16_t;
typedef int32_t spx_int32_t;
typedef uint32_t spx_uint32_t;
#endif
+343
View File
@@ -0,0 +1,343 @@
/* Copyright (C) 2007 Jean-Marc Valin
File: speex_resampler.h
Resampling code
The design goals of this code are:
- Very fast algorithm
- Low memory requirement
- Good *perceptual* quality (and not best SNR)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SPEEX_RESAMPLER_H
#define SPEEX_RESAMPLER_H
#ifdef OUTSIDE_SPEEX
/********* WARNING: MENTAL SANITY ENDS HERE *************/
/* If the resampler is defined outside of Speex, we change the symbol names so that
there won't be any clash if linking with Speex later on. */
/* #define RANDOM_PREFIX your software name here */
#ifndef RANDOM_PREFIX
#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
#endif
#define CAT_PREFIX2(a,b) a ## b
#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
#define spx_int16_t short
#define spx_int32_t int
#define spx_uint16_t unsigned short
#define spx_uint32_t unsigned int
#define speex_assert(cond)
#else /* OUTSIDE_SPEEX */
#include "speexdsp_types.h"
#endif /* OUTSIDE_SPEEX */
#ifdef __cplusplus
extern "C" {
#endif
#define SPEEX_RESAMPLER_QUALITY_MAX 10
#define SPEEX_RESAMPLER_QUALITY_MIN 0
#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
#define SPEEX_RESAMPLER_QUALITY_VOIP 3
#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
enum {
RESAMPLER_ERR_SUCCESS = 0,
RESAMPLER_ERR_ALLOC_FAILED = 1,
RESAMPLER_ERR_BAD_STATE = 2,
RESAMPLER_ERR_INVALID_ARG = 3,
RESAMPLER_ERR_PTR_OVERLAP = 4,
RESAMPLER_ERR_OVERFLOW = 5,
RESAMPLER_ERR_MAX_ERROR
};
struct SpeexResamplerState_;
typedef struct SpeexResamplerState_ SpeexResamplerState;
/** Create a new resampler with integer input and output rates.
* @param nb_channels Number of channels to be processed
* @param in_rate Input sampling rate (integer number of Hz).
* @param out_rate Output sampling rate (integer number of Hz).
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
* and 10 has very high quality.
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels,
spx_uint32_t in_rate,
spx_uint32_t out_rate,
int quality,
int *err);
/** Create a new resampler with fractional input/output rates. The sampling
* rate ratio is an arbitrary rational number with both the numerator and
* denominator being 32-bit integers.
* @param nb_channels Number of channels to be processed
* @param ratio_num Numerator of the sampling rate ratio
* @param ratio_den Denominator of the sampling rate ratio
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
* @param quality Resampling quality between 0 and 10, where 0 has poor quality
* and 10 has very high quality.
* @return Newly created resampler state
* @retval NULL Error: not enough memory
*/
SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels,
spx_uint32_t ratio_num,
spx_uint32_t ratio_den,
spx_uint32_t in_rate,
spx_uint32_t out_rate,
int quality,
int *err);
/** Destroy a resampler state.
* @param st Resampler state
*/
void speex_resampler_destroy(SpeexResamplerState *st);
/** Resample a float array. The input and output buffers must *not* overlap.
* @param st Resampler state
* @param channel_index Index of the channel to process for the multi-channel
* base (0 otherwise)
* @param in Input buffer
* @param in_len Number of input samples in the input buffer. Returns the
* number of samples processed
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
int speex_resampler_process_float(SpeexResamplerState *st,
spx_uint32_t channel_index,
const float *in,
spx_uint32_t *in_len,
float *out,
spx_uint32_t *out_len);
/** Resample an int array. The input and output buffers must *not* overlap.
* @param st Resampler state
* @param channel_index Index of the channel to process for the multi-channel
* base (0 otherwise)
* @param in Input buffer
* @param in_len Number of input samples in the input buffer. Returns the number
* of samples processed
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written
*/
int speex_resampler_process_int(SpeexResamplerState *st,
spx_uint32_t channel_index,
const spx_int16_t *in,
spx_uint32_t *in_len,
spx_int16_t *out,
spx_uint32_t *out_len);
/** Resample an interleaved float array. The input and output buffers must *not* overlap.
* @param st Resampler state
* @param in Input buffer
* @param in_len Number of input samples in the input buffer. Returns the number
* of samples processed. This is all per-channel.
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
int speex_resampler_process_interleaved_float(SpeexResamplerState *st,
const float *in,
spx_uint32_t *in_len,
float *out,
spx_uint32_t *out_len);
/** Resample an interleaved int array. The input and output buffers must *not* overlap.
* @param st Resampler state
* @param in Input buffer
* @param in_len Number of input samples in the input buffer. Returns the number
* of samples processed. This is all per-channel.
* @param out Output buffer
* @param out_len Size of the output buffer. Returns the number of samples written.
* This is all per-channel.
*/
int speex_resampler_process_interleaved_int(SpeexResamplerState *st,
const spx_int16_t *in,
spx_uint32_t *in_len,
spx_int16_t *out,
spx_uint32_t *out_len);
/** Set (change) the input/output sampling rates (integer value).
* @param st Resampler state
* @param in_rate Input sampling rate (integer number of Hz).
* @param out_rate Output sampling rate (integer number of Hz).
*/
int speex_resampler_set_rate(SpeexResamplerState *st,
spx_uint32_t in_rate,
spx_uint32_t out_rate);
/** Get the current input/output sampling rates (integer value).
* @param st Resampler state
* @param in_rate Input sampling rate (integer number of Hz) copied.
* @param out_rate Output sampling rate (integer number of Hz) copied.
*/
void speex_resampler_get_rate(SpeexResamplerState *st,
spx_uint32_t *in_rate,
spx_uint32_t *out_rate);
/** Set (change) the input/output sampling rates and resampling ratio
* (fractional values in Hz supported).
* @param st Resampler state
* @param ratio_num Numerator of the sampling rate ratio
* @param ratio_den Denominator of the sampling rate ratio
* @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
* @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
*/
int speex_resampler_set_rate_frac(SpeexResamplerState *st,
spx_uint32_t ratio_num,
spx_uint32_t ratio_den,
spx_uint32_t in_rate,
spx_uint32_t out_rate);
/** Get the current resampling ratio. This will be reduced to the least
* common denominator.
* @param st Resampler state
* @param ratio_num Numerator of the sampling rate ratio copied
* @param ratio_den Denominator of the sampling rate ratio copied
*/
void speex_resampler_get_ratio(SpeexResamplerState *st,
spx_uint32_t *ratio_num,
spx_uint32_t *ratio_den);
/** Set (change) the conversion quality.
* @param st Resampler state
* @param quality Resampling quality between 0 and 10, where 0 has poor
* quality and 10 has very high quality.
*/
int speex_resampler_set_quality(SpeexResamplerState *st,
int quality);
/** Get the conversion quality.
* @param st Resampler state
* @param quality Resampling quality between 0 and 10, where 0 has poor
* quality and 10 has very high quality.
*/
void speex_resampler_get_quality(SpeexResamplerState *st,
int *quality);
/** Set (change) the input stride.
* @param st Resampler state
* @param stride Input stride
*/
void speex_resampler_set_input_stride(SpeexResamplerState *st,
spx_uint32_t stride);
/** Get the input stride.
* @param st Resampler state
* @param stride Input stride copied
*/
void speex_resampler_get_input_stride(SpeexResamplerState *st,
spx_uint32_t *stride);
/** Set (change) the output stride.
* @param st Resampler state
* @param stride Output stride
*/
void speex_resampler_set_output_stride(SpeexResamplerState *st,
spx_uint32_t stride);
/** Get the output stride.
* @param st Resampler state copied
* @param stride Output stride
*/
void speex_resampler_get_output_stride(SpeexResamplerState *st,
spx_uint32_t *stride);
/** Get the latency introduced by the resampler measured in input samples.
* @param st Resampler state
*/
int speex_resampler_get_input_latency(SpeexResamplerState *st);
/** Get the latency introduced by the resampler measured in output samples.
* @param st Resampler state
*/
int speex_resampler_get_output_latency(SpeexResamplerState *st);
/** Make sure that the first samples to go out of the resamplers don't have
* leading zeros. This is only useful before starting to use a newly created
* resampler. It is recommended to use that when resampling an audio file, as
* it will generate a file with the same length. For real-time processing,
* it is probably easier not to use this call (so that the output duration
* is the same for the first frame).
* @param st Resampler state
*/
int speex_resampler_skip_zeros(SpeexResamplerState *st);
/** Reset a resampler so a new (unrelated) stream can be processed.
* @param st Resampler state
*/
int speex_resampler_reset_mem(SpeexResamplerState *st);
/** Returns the English meaning for an error code
* @param err Error code
* @return English string
*/
const char *speex_resampler_strerror(int err);
#ifdef __cplusplus
}
#endif
#endif
+115
View File
@@ -0,0 +1,115 @@
/* Copyright (C) 2002 Jean-Marc Valin */
/**
@file stack_alloc.h
@brief Temporary memory allocation on stack
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STACK_ALLOC_H
#define STACK_ALLOC_H
#ifdef USE_ALLOCA
# ifdef WIN32
# include <malloc.h>
# else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# include <stdlib.h>
# endif
# endif
#endif
/**
* @def ALIGN(stack, size)
*
* Aligns the stack to a 'size' boundary
*
* @param stack Stack
* @param size New size boundary
*/
/**
* @def PUSH(stack, size, type)
*
* Allocates 'size' elements of type 'type' on the stack
*
* @param stack Stack
* @param size Number of elements
* @param type Type of element
*/
/**
* @def VARDECL(var)
*
* Declare variable on stack
*
* @param var Variable to declare
*/
/**
* @def ALLOC(var, size, type)
*
* Allocate 'size' elements of 'type' on stack
*
* @param var Name of variable to allocate
* @param size Number of elements
* @param type Type of element
*/
#ifdef ENABLE_VALGRIND
#include <valgrind/memcheck.h>
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
#else
#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
#endif
#if defined(VAR_ARRAYS)
#define VARDECL(var)
#define ALLOC(var, size, type) type var[size]
#elif defined(USE_ALLOCA)
#define VARDECL(var) var
#define ALLOC(var, size, type) var = alloca(sizeof(type)*(size))
#else
#define VARDECL(var) var
#define ALLOC(var, size, type) var = PUSH(stack, size, type)
#endif
#endif
+37
View File
@@ -0,0 +1,37 @@
set(SRCS
include/discord_register.h
include/discord_rpc.h
src/backoff.h
src/connection.h
src/discord_rpc.cpp
src/msg_queue.h
src/rpc_connection.cpp
src/rpc_connection.h
src/serialization.cpp
src/serialization.h
)
add_library(discord-rpc ${SRCS})
target_include_directories(discord-rpc PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(discord-rpc rapidjson)
# Needed for macOS compile.
set_property(TARGET discord-rpc PROPERTY CXX_STANDARD 17)
set_property(TARGET discord-rpc PROPERTY CXX_STANDARD_REQUIRED ON)
if(WIN32)
target_sources(discord-rpc PRIVATE
src/connection_win.cpp
src/discord_register_win.cpp
)
elseif(APPLE)
target_sources(discord-rpc PRIVATE
src/connection_unix.cpp
src/discord_register_osx.m
)
elseif(UNIX)
target_sources(discord-rpc PRIVATE
src/connection_unix.cpp
src/discord_register_linux.cpp
)
endif()
+19
View File
@@ -0,0 +1,19 @@
Copyright 2017 Discord, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{E960DFDF-1BD3-4C29-B251-D1A0919C9B09}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Devel))" Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="..\..\common\vsprops\CodeGen_Release.props" />
<Import Condition="!$(Configuration.Contains(Release))" Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<ClInclude Include="include\discord_register.h" />
<ClInclude Include="include\discord_rpc.h" />
<ClInclude Include="src\backoff.h" />
<ClInclude Include="src\connection.h" />
<ClInclude Include="src\msg_queue.h" />
<ClInclude Include="src\rpc_connection.h" />
<ClInclude Include="src\serialization.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\connection_win.cpp" />
<ClCompile Include="src\discord_register_win.cpp" />
<ClCompile Include="src\discord_rpc.cpp" />
<ClCompile Include="src\rpc_connection.cpp" />
<ClCompile Include="src\serialization.cpp" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\rapidjson\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="include\discord_rpc.h" />
<ClInclude Include="include\discord_register.h" />
<ClInclude Include="src\connection.h" />
<ClInclude Include="src\msg_queue.h" />
<ClInclude Include="src\rpc_connection.h" />
<ClInclude Include="src\serialization.h" />
<ClInclude Include="src\backoff.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\connection_win.cpp" />
<ClCompile Include="src\discord_register_win.cpp" />
<ClCompile Include="src\discord_rpc.cpp" />
<ClCompile Include="src\rpc_connection.cpp" />
<ClCompile Include="src\serialization.cpp" />
</ItemGroup>
</Project>
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#if defined(DISCORD_DYNAMIC_LIB)
#if defined(_WIN32)
#if defined(DISCORD_BUILDING_SDK)
#define DISCORD_EXPORT __declspec(dllexport)
#else
#define DISCORD_EXPORT __declspec(dllimport)
#endif
#else
#define DISCORD_EXPORT __attribute__((visibility("default")))
#endif
#else
#define DISCORD_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command);
DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId);
#ifdef __cplusplus
}
#endif

Some files were not shown because too many files have changed in this diff Show More