Fixed Mat and CMakeLists
This commit is contained in:
parent
25762b0c29
commit
681c0d09be
312
CMakeLists.txt
312
CMakeLists.txt
@ -40,179 +40,179 @@ endif ()
|
|||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
set(EHS_SOURCES
|
set(EHS_SOURCES
|
||||||
src/EHS.cpp include/ehs/EHS.h
|
src/EHS.cpp include/ehs/EHS.h
|
||||||
src/Type.cpp include/ehs/Type.h
|
src/Type.cpp include/ehs/Type.h
|
||||||
src/BaseObj.cpp include/ehs/BaseObj.h
|
src/BaseObj.cpp include/ehs/BaseObj.h
|
||||||
src/GC.cpp include/ehs/GC.h
|
src/GC.cpp include/ehs/GC.h
|
||||||
src/Log.cpp include/ehs/Log.h
|
src/Log.cpp include/ehs/Log.h
|
||||||
src/URI.cpp include/ehs/URI.h
|
src/URI.cpp include/ehs/URI.h
|
||||||
src/Math.cpp include/ehs/Math.h
|
src/Math.cpp include/ehs/Math.h
|
||||||
src/Color4.cpp include/ehs/Color4.h
|
src/Color4.cpp include/ehs/Color4.h
|
||||||
src/Color3.cpp include/ehs/Color3.h
|
src/Color3.cpp include/ehs/Color3.h
|
||||||
src/Version.cpp include/ehs/Version.h
|
src/Version.cpp include/ehs/Version.h
|
||||||
src/Base64.cpp include/ehs/Base64.h
|
src/Base64.cpp include/ehs/Base64.h
|
||||||
src/Data.cpp include/ehs/Data.h
|
src/Data.cpp include/ehs/Data.h
|
||||||
src/Range.cpp include/ehs/Range.h
|
src/Range.cpp include/ehs/Range.h
|
||||||
src/Util.cpp include/ehs/Util.h
|
src/Util.cpp include/ehs/Util.h
|
||||||
src/Task.cpp include/ehs/Task.h
|
src/Task.cpp include/ehs/Task.h
|
||||||
src/DataType.cpp include/ehs/DataType.h
|
src/DataType.cpp include/ehs/DataType.h
|
||||||
include/ehs/Anchor.h
|
include/ehs/Anchor.h
|
||||||
include/ehs/Dock.h
|
include/ehs/Dock.h
|
||||||
include/ehs/HashMap.h
|
include/ehs/HashMap.h
|
||||||
include/ehs/HRNG.h
|
include/ehs/HRNG.h
|
||||||
include/ehs/Link.h
|
include/ehs/Link.h
|
||||||
include/ehs/LinkedList.h
|
include/ehs/LinkedList.h
|
||||||
include/ehs/Mat2.h
|
include/ehs/Mat2.h
|
||||||
include/ehs/Mat3.h
|
include/ehs/Mat3.h
|
||||||
include/ehs/Mat4.h
|
include/ehs/Mat4.h
|
||||||
include/ehs/PRNG.h
|
include/ehs/PRNG.h
|
||||||
include/ehs/Quat.h
|
include/ehs/Quat.h
|
||||||
include/ehs/Rect.h
|
include/ehs/Rect.h
|
||||||
include/ehs/Str.h
|
include/ehs/Str.h
|
||||||
include/ehs/Types.h
|
include/ehs/Types.h
|
||||||
include/ehs/UTF.h
|
include/ehs/UTF.h
|
||||||
include/ehs/Vec2.h
|
include/ehs/Vec2.h
|
||||||
include/ehs/Vec3.h
|
include/ehs/Vec3.h
|
||||||
include/ehs/Vec4.h
|
include/ehs/Vec4.h
|
||||||
include/ehs/Serializer.h
|
include/ehs/Serializer.h
|
||||||
include/ehs/Array.h
|
include/ehs/Array.h
|
||||||
include/ehs/Vector.h
|
include/ehs/Vector.h
|
||||||
include/ehs/SArray.h
|
include/ehs/SArray.h
|
||||||
src/PtrData.cpp include/ehs/PtrData.h
|
src/PtrData.cpp include/ehs/PtrData.h
|
||||||
include/ehs/UniPtr.h
|
include/ehs/UniPtr.h
|
||||||
include/ehs/ShdPtr.h
|
include/ehs/ShdPtr.h
|
||||||
include/ehs/WkPtr.h
|
include/ehs/WkPtr.h
|
||||||
|
|
||||||
src/db/DbVarTmpl.cpp include/ehs/db/DbVarTmpl.h
|
src/db/DbVarTmpl.cpp include/ehs/db/DbVarTmpl.h
|
||||||
|
|
||||||
src/system/CPU.cpp include/ehs/system/CPU.h
|
src/system/CPU.cpp include/ehs/system/CPU.h
|
||||||
src/system/Thread.cpp include/ehs/system/Thread.h
|
src/system/Thread.cpp include/ehs/system/Thread.h
|
||||||
src/system/BaseMutex.cpp include/ehs/system/BaseMutex.h
|
src/system/BaseMutex.cpp include/ehs/system/BaseMutex.h
|
||||||
src/system/BaseSemaphore.cpp include/ehs/system/BaseSemaphore.h
|
src/system/BaseSemaphore.cpp include/ehs/system/BaseSemaphore.h
|
||||||
src/system/BaseSystem.cpp include/ehs/system/BaseSystem.h
|
src/system/BaseSystem.cpp include/ehs/system/BaseSystem.h
|
||||||
src/system/BaseOpen.cpp include/ehs/system/BaseOpen.h
|
src/system/BaseOpen.cpp include/ehs/system/BaseOpen.h
|
||||||
include/ehs/system/Architecture.h
|
include/ehs/system/Architecture.h
|
||||||
include/ehs/system/Mutex.h
|
include/ehs/system/Mutex.h
|
||||||
include/ehs/system/Open.h
|
include/ehs/system/Open.h
|
||||||
include/ehs/system/OS.h
|
include/ehs/system/OS.h
|
||||||
include/ehs/system/Semaphore.h
|
include/ehs/system/Semaphore.h
|
||||||
include/ehs/system/System.h
|
include/ehs/system/System.h
|
||||||
|
|
||||||
src/json/Json.cpp include/ehs/json/Json.h
|
src/json/Json.cpp include/ehs/json/Json.h
|
||||||
src/json/JsonBase.cpp include/ehs/json/JsonBase.h
|
src/json/JsonBase.cpp include/ehs/json/JsonBase.h
|
||||||
src/json/JsonNum.cpp include/ehs/json/JsonNum.h
|
src/json/JsonNum.cpp include/ehs/json/JsonNum.h
|
||||||
src/json/JsonBool.cpp include/ehs/json/JsonBool.h
|
src/json/JsonBool.cpp include/ehs/json/JsonBool.h
|
||||||
src/json/JsonStr.cpp include/ehs/json/JsonStr.h
|
src/json/JsonStr.cpp include/ehs/json/JsonStr.h
|
||||||
src/json/JsonObj.cpp include/ehs/json/JsonObj.h
|
src/json/JsonObj.cpp include/ehs/json/JsonObj.h
|
||||||
src/json/JsonArray.cpp include/ehs/json/JsonArray.h
|
src/json/JsonArray.cpp include/ehs/json/JsonArray.h
|
||||||
src/json/JsonVar.cpp include/ehs/json/JsonVar.h
|
src/json/JsonVar.cpp include/ehs/json/JsonVar.h
|
||||||
|
|
||||||
src/io/Resource.cpp include/ehs/io/Resource.h
|
src/io/Resource.cpp include/ehs/io/Resource.h
|
||||||
src/io/Console.cpp include/ehs/io/Console.h
|
src/io/Console.cpp include/ehs/io/Console.h
|
||||||
src/io/RIFF_Chunk.cpp include/ehs/io/RIFF_Chunk.h
|
src/io/RIFF_Chunk.cpp include/ehs/io/RIFF_Chunk.h
|
||||||
src/io/RIFF.cpp include/ehs/io/RIFF.h
|
src/io/RIFF.cpp include/ehs/io/RIFF.h
|
||||||
src/io/BaseWindow.cpp include/ehs/io/BaseWindow.h
|
src/io/BaseWindow.cpp include/ehs/io/BaseWindow.h
|
||||||
src/io/BaseFile.cpp include/ehs/io/BaseFile.h
|
src/io/BaseFile.cpp include/ehs/io/BaseFile.h
|
||||||
src/io/Glyph.cpp include/ehs/io/Glyph.h
|
src/io/Glyph.cpp include/ehs/io/Glyph.h
|
||||||
src/io/FontAtlas.cpp include/ehs/io/FontAtlas.h
|
src/io/FontAtlas.cpp include/ehs/io/FontAtlas.h
|
||||||
src/io/BaseFileMonitor.cpp include/ehs/io/BaseFileMonitor.h
|
src/io/BaseFileMonitor.cpp include/ehs/io/BaseFileMonitor.h
|
||||||
include/ehs/io/COM.h
|
include/ehs/io/COM.h
|
||||||
include/ehs/io/File.h
|
include/ehs/io/File.h
|
||||||
include/ehs/io/FileMonitor.h
|
include/ehs/io/FileMonitor.h
|
||||||
include/ehs/io/Window.h
|
include/ehs/io/Window.h
|
||||||
|
|
||||||
src/io/socket/Request.cpp include/ehs/io/socket/Request.h
|
src/io/socket/Request.cpp include/ehs/io/socket/Request.h
|
||||||
src/io/socket/Response.cpp include/ehs/io/socket/Response.h
|
src/io/socket/Response.cpp include/ehs/io/socket/Response.h
|
||||||
src/io/socket/BaseDNS.cpp include/ehs/io/socket/BaseDNS.h
|
src/io/socket/BaseDNS.cpp include/ehs/io/socket/BaseDNS.h
|
||||||
src/io/socket/BaseUDP.cpp include/ehs/io/socket/BaseUDP.h
|
src/io/socket/BaseUDP.cpp include/ehs/io/socket/BaseUDP.h
|
||||||
src/io/socket/BaseTCP.cpp include/ehs/io/socket/BaseTCP.h
|
src/io/socket/BaseTCP.cpp include/ehs/io/socket/BaseTCP.h
|
||||||
src/io/socket/SSL.cpp include/ehs/io/socket/SSL.h
|
src/io/socket/SSL.cpp include/ehs/io/socket/SSL.h
|
||||||
|
|
||||||
src/io/socket/rest/Twitch.cpp include/ehs/io/socket/rest/Twitch.h
|
src/io/socket/rest/Twitch.cpp include/ehs/io/socket/rest/Twitch.h
|
||||||
src/io/socket/rest/TwitchChat.cpp include/ehs/io/socket/rest/TwitchChat.h
|
src/io/socket/rest/TwitchChat.cpp include/ehs/io/socket/rest/TwitchChat.h
|
||||||
src/io/socket/rest/Spotify.cpp include/ehs/io/socket/rest/Spotify.h
|
src/io/socket/rest/Spotify.cpp include/ehs/io/socket/rest/Spotify.h
|
||||||
include/ehs/io/socket/Socket.h
|
include/ehs/io/socket/Socket.h
|
||||||
include/ehs/io/socket/TCP.h
|
include/ehs/io/socket/TCP.h
|
||||||
include/ehs/io/socket/UDP.h
|
include/ehs/io/socket/UDP.h
|
||||||
include/ehs/io/socket/DNS.h
|
include/ehs/io/socket/DNS.h
|
||||||
|
|
||||||
src/io/audio/Audio.cpp include/ehs/io/audio/Audio.h
|
src/io/audio/Audio.cpp include/ehs/io/audio/Audio.h
|
||||||
src/io/audio/BaseAudioDevice.cpp include/ehs/io/audio/BaseAudioDevice.h
|
src/io/audio/BaseAudioDevice.cpp include/ehs/io/audio/BaseAudioDevice.h
|
||||||
src/io/audio/AudioCodec.cpp include/ehs/io/audio/AudioCodec.h
|
src/io/audio/AudioCodec.cpp include/ehs/io/audio/AudioCodec.h
|
||||||
include/ehs/io/audio/AudioDevice.h
|
include/ehs/io/audio/AudioDevice.h
|
||||||
|
|
||||||
src/io/img/PNG.cpp include/ehs/io/img/PNG.h
|
src/io/img/PNG.cpp include/ehs/io/img/PNG.h
|
||||||
src/io/img/Img.cpp include/ehs/io/img/Img.h
|
src/io/img/Img.cpp include/ehs/io/img/Img.h
|
||||||
src/io/img/PNG_Chunk.cpp include/ehs/io/img/PNG_Chunk.h
|
src/io/img/PNG_Chunk.cpp include/ehs/io/img/PNG_Chunk.h
|
||||||
src/io/img/ImgCodec.cpp include/ehs/io/img/ImgCodec.h
|
src/io/img/ImgCodec.cpp include/ehs/io/img/ImgCodec.h
|
||||||
|
|
||||||
include/ehs/io/mdl/Vertex.h
|
include/ehs/io/mdl/Vertex.h
|
||||||
src/io/model/Mesh.cpp include/ehs/io/mdl/Mesh.h
|
src/io/model/Mesh.cpp include/ehs/io/mdl/Mesh.h
|
||||||
src/io/model/Bone.cpp include/ehs/io/mdl/Bone.h
|
src/io/model/Bone.cpp include/ehs/io/mdl/Bone.h
|
||||||
src/io/model/Mdl.cpp include/ehs/io/mdl/Mdl.h
|
src/io/model/Mdl.cpp include/ehs/io/mdl/Mdl.h
|
||||||
src/io/model/Animation.cpp include/ehs/io/mdl/Animation.h
|
src/io/model/Animation.cpp include/ehs/io/mdl/Animation.h
|
||||||
src/io/model/AnimBone.cpp include/ehs/io/mdl/AnimBone.h
|
src/io/model/AnimBone.cpp include/ehs/io/mdl/AnimBone.h
|
||||||
src/io/model/KeyFrame.cpp include/ehs/io/mdl/KeyFrame.h
|
src/io/model/KeyFrame.cpp include/ehs/io/mdl/KeyFrame.h
|
||||||
src/io/model/PropertyChange.cpp include/ehs/io/mdl/PropertyChange.h
|
src/io/model/PropertyChange.cpp include/ehs/io/mdl/PropertyChange.h
|
||||||
|
|
||||||
src/io/hid/ButtonState.cpp include/ehs/io/hid/ButtonState.h
|
src/io/hid/ButtonState.cpp include/ehs/io/hid/ButtonState.h
|
||||||
src/io/hid/Button.cpp include/ehs/io/hid/Button.h
|
src/io/hid/Button.cpp include/ehs/io/hid/Button.h
|
||||||
src/io/hid/Mouse.cpp include/ehs/io/hid/Mouse.h
|
src/io/hid/Mouse.cpp include/ehs/io/hid/Mouse.h
|
||||||
src/io/hid/Keyboard.cpp include/ehs/io/hid/Keyboard.h
|
src/io/hid/Keyboard.cpp include/ehs/io/hid/Keyboard.h
|
||||||
src/io/hid/HID.cpp include/ehs/io/hid/HID.h
|
src/io/hid/HID.cpp include/ehs/io/hid/HID.h
|
||||||
src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h
|
src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h
|
||||||
src/io/hid/Input.cpp include/ehs/io/hid/Input.h
|
src/io/hid/Input.cpp include/ehs/io/hid/Input.h
|
||||||
src/io/model/MdlCodec.cpp
|
src/io/model/MdlCodec.cpp
|
||||||
include/ehs/io/mdl/MdlCodec.h
|
include/ehs/io/mdl/MdlCodec.h
|
||||||
include/ehs/io/UsbBase.h
|
include/ehs/io/UsbBase.h
|
||||||
src/io/UsbBase.cpp
|
src/io/UsbBase.cpp
|
||||||
include/ehs/db/DbTable.h
|
include/ehs/db/DbTable.h
|
||||||
include/ehs/db/DbObject.h
|
include/ehs/db/DbObject.h
|
||||||
include/ehs/db/DbVar.h
|
include/ehs/db/DbVar.h
|
||||||
src/db/DbVar.cpp
|
src/db/DbVar.cpp
|
||||||
include/ehs/db/Database.h
|
include/ehs/db/Database.h
|
||||||
src/db/DbObject.cpp
|
src/db/DbObject.cpp
|
||||||
src/db/Database.cpp
|
src/db/Database.cpp
|
||||||
src/db/Database.cpp
|
src/db/Database.cpp
|
||||||
src/db/DbTable.cpp
|
src/db/DbTable.cpp
|
||||||
include/ehs/io/BaseDirectory.h
|
include/ehs/io/BaseDirectory.h
|
||||||
src/io/BaseDirectory.cpp
|
src/io/BaseDirectory.cpp
|
||||||
include/ehs/io/Directory.h
|
include/ehs/io/Directory.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if (IS_OS_WINDOWS)
|
if (IS_OS_WINDOWS)
|
||||||
list(APPEND EHS_SOURCES
|
list(APPEND EHS_SOURCES
|
||||||
src/io/socket/UDP_W32.cpp include/ehs/io/socket/UDP_W32.h
|
src/io/socket/UDP_W32.cpp include/ehs/io/socket/UDP_W32.h
|
||||||
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
|
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
|
||||||
src/io/socket/DNS_W32.cpp include/ehs/io/socket/DNS_W32.h
|
src/io/socket/DNS_W32.cpp include/ehs/io/socket/DNS_W32.h
|
||||||
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
|
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
|
||||||
src/system/System_W32.cpp include/ehs/system/System_W32.h
|
src/system/System_W32.cpp include/ehs/system/System_W32.h
|
||||||
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
|
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
|
||||||
src/system/Open_W32.cpp include/ehs/system/Open_W32.h
|
src/system/Open_W32.cpp include/ehs/system/Open_W32.h
|
||||||
src/io/audio/audioDevice_W32.cpp include/ehs/io/audio/audioDevice_W32.h
|
src/io/audio/audioDevice_W32.cpp include/ehs/io/audio/audioDevice_W32.h
|
||||||
src/io/File_W32.cpp include/ehs/io/File_W32.h
|
src/io/File_W32.cpp include/ehs/io/File_W32.h
|
||||||
src/io/FileMonitor_W32.cpp include/ehs/io/FileMonitor_W32.h
|
src/io/FileMonitor_W32.cpp include/ehs/io/FileMonitor_W32.h
|
||||||
src/io/Window_W32.cpp include/ehs/io/Window_W32.h
|
src/io/Window_W32.cpp include/ehs/io/Window_W32.h
|
||||||
src/io/COM.cpp include/ehs/io/COM.h
|
src/io/COM.cpp include/ehs/io/COM.h
|
||||||
src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm
|
src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm
|
||||||
src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h
|
src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h
|
||||||
)
|
)
|
||||||
elseif (IS_OS_LINUX)
|
elseif (IS_OS_LINUX)
|
||||||
list(APPEND EHS_SOURCES
|
list(APPEND EHS_SOURCES
|
||||||
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
|
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
|
||||||
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
|
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
|
||||||
src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h
|
src/io/socket/DNS_LNX.cpp include/ehs/io/socket/DNS_LNX.h
|
||||||
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
|
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
|
||||||
src/system/System_LNX.cpp include/ehs/system/System_LNX.h
|
src/system/System_LNX.cpp include/ehs/system/System_LNX.h
|
||||||
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h
|
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h
|
||||||
src/io/File_UNX.cpp include/ehs/io/File_UNX.h
|
src/io/File_UNX.cpp include/ehs/io/File_UNX.h
|
||||||
src/io/FileMonitor_UNX.cpp include/ehs/io/FileMonitor_UNX.h
|
src/io/FileMonitor_UNX.cpp include/ehs/io/FileMonitor_UNX.h
|
||||||
src/system/Mutex_PT.cpp include/ehs/system/Mutex_PT.h
|
src/system/Mutex_PT.cpp include/ehs/system/Mutex_PT.h
|
||||||
src/io/audio/AudioDevice_ALSA.cpp include/ehs/io/audio/AudioDevice_ALSA.h
|
src/io/audio/AudioDevice_PW.cpp include/ehs/io/audio/AudioDevice_PW.h
|
||||||
src/system/FileSystem.cpp include/ehs/system/FileSystem.h
|
src/system/FileSystem.cpp include/ehs/system/FileSystem.h
|
||||||
src/system/User.cpp include/ehs/system/User.h
|
src/system/User.cpp include/ehs/system/User.h
|
||||||
src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h
|
src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h
|
||||||
src/io/Usb_LNX.cpp include/ehs/io/Usb_LNX.h
|
src/io/Usb_LNX.cpp include/ehs/io/Usb_LNX.h
|
||||||
)
|
)
|
||||||
|
|
||||||
#set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
|
#set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
#if defined(EHS_OS_WINDOWS)
|
#if defined(EHS_OS_WINDOWS)
|
||||||
#include "AudioDevice_W32.h"
|
#include "AudioDevice_W32.h"
|
||||||
#elif defined(EHS_OS_LINUX)
|
#elif defined(EHS_OS_LINUX)
|
||||||
#include "AudioDevice_ALSA.h"
|
#include "AudioDevice_PW.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,16 +3,15 @@
|
|||||||
#include "ehs/EHS.h"
|
#include "ehs/EHS.h"
|
||||||
#include "BaseAudioDevice.h"
|
#include "BaseAudioDevice.h"
|
||||||
|
|
||||||
#include <spa/param/audio/format-utils.h>
|
|
||||||
#include <pipewire/pipewire.h>
|
#include <pipewire/pipewire.h>
|
||||||
#include <pipewire/loop.h>
|
#include <pipewire/loop.h>
|
||||||
#include <pipewire/context.h>
|
#include <pipewire/context.h>
|
||||||
#include <pipewire/stream.h>
|
#include <pipewire/stream.h>
|
||||||
#include <pipewire/keys.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
class EHS_LIB_IO AudioDevice : public BaseAudioDevice
|
class EHS_LIB_IO AudioDevice final : public BaseAudioDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static Array<AudioDevice> devices;
|
static Array<AudioDevice> devices;
|
||||||
@ -24,11 +23,14 @@ namespace ehs
|
|||||||
pw_loop *loop;
|
pw_loop *loop;
|
||||||
pw_context *context;
|
pw_context *context;
|
||||||
pw_core *core;
|
pw_core *core;
|
||||||
pw_stream *stream;
|
pw_stream *input;
|
||||||
|
pw_stream *output;
|
||||||
|
|
||||||
static void RegistryEventGlobal(void *user_data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props);
|
static void RegistryEventGlobal(void *data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props);
|
||||||
|
|
||||||
static void RegistryEventGlobalRemove(void *user_data, UInt_32 id);
|
static void RegistryEventGlobalRemove(void *data, UInt_32 id);
|
||||||
|
|
||||||
|
static void OnParamChanged(void *data, UInt_32 id, const spa_pod *param);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~AudioDevice() override;
|
~AudioDevice() override;
|
||||||
@ -43,18 +45,23 @@ namespace ehs
|
|||||||
|
|
||||||
AudioDevice& operator=(const AudioDevice& device);
|
AudioDevice& operator=(const AudioDevice& device);
|
||||||
|
|
||||||
void Release() override;
|
|
||||||
|
|
||||||
void OpenStream() override;
|
void OpenStream() override;
|
||||||
|
|
||||||
void CloseStream() override;
|
void CloseStream() override;
|
||||||
|
|
||||||
UInt_64 SendStream(void *data, UInt_64 size) override;
|
UInt_64 SendStream(const void *data, UInt_64 size) override;
|
||||||
|
|
||||||
|
UInt_64 ReceiveStream(void *data, UInt_64 size) override;
|
||||||
|
|
||||||
|
bool IsStreaming() const override;
|
||||||
|
|
||||||
bool IsValid() const override;
|
bool IsValid() const override;
|
||||||
|
|
||||||
static AudioDevice GetDefault(AudioDeviceType type);
|
static AudioDevice GetDefault(AudioDeviceType type);
|
||||||
|
|
||||||
static Array<AudioDevice> Get(AudioDeviceType type, AudioDeviceState state);
|
static Array<AudioDevice> Get(AudioDeviceType type, AudioDeviceState state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Str_8 GetCategory() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ struct IMMDevice;
|
|||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
class EHS_LIB_IO AudioDevice : public BaseAudioDevice
|
class EHS_LIB_IO AudioDevice final : public BaseAudioDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
IMMDevice* hdl;
|
IMMDevice* hdl;
|
||||||
|
@ -10,8 +10,8 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
enum class AudioDeviceType
|
enum class AudioDeviceType
|
||||||
{
|
{
|
||||||
OUTPUT = 0x0,
|
|
||||||
INPUT = 0x1,
|
INPUT = 0x1,
|
||||||
|
OUTPUT = 0x0,
|
||||||
ALL = 0x2
|
ALL = 0x2
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,13 +28,12 @@ namespace ehs
|
|||||||
protected:
|
protected:
|
||||||
AudioDeviceType type;
|
AudioDeviceType type;
|
||||||
DataType dataType;
|
DataType dataType;
|
||||||
UInt_16 bitDepth;
|
UInt_16 byteDepth;
|
||||||
UInt_32 sampleRate;
|
UInt_32 sampleRate;
|
||||||
UInt_32 channels;
|
UInt_32 channels;
|
||||||
UInt_32 period;
|
UInt_32 period;
|
||||||
UInt_32 latency;
|
UInt_32 latency;
|
||||||
UInt_64 maxFrames;
|
UInt_64 maxFrames;
|
||||||
bool streaming;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~BaseAudioDevice() = default;
|
virtual ~BaseAudioDevice() = default;
|
||||||
@ -45,19 +44,15 @@ namespace ehs
|
|||||||
|
|
||||||
BaseAudioDevice& operator=(const BaseAudioDevice& device);
|
BaseAudioDevice& operator=(const BaseAudioDevice& device);
|
||||||
|
|
||||||
virtual void Release();
|
|
||||||
|
|
||||||
virtual void OpenStream();
|
virtual void OpenStream();
|
||||||
|
|
||||||
virtual void CloseStream();
|
virtual void CloseStream();
|
||||||
|
|
||||||
virtual UInt_64 SendStream(void *data, UInt_64 size);
|
virtual UInt_64 SendStream(const void *data, UInt_64 size);
|
||||||
|
|
||||||
virtual UInt_64 GetAvailFrames() const;
|
virtual UInt_64 ReceiveStream(void *data, UInt_64 size);
|
||||||
|
|
||||||
virtual Byte* Map(UInt_64* offset, UInt_64* frames);
|
void BridgeStreams(UInt_64 bufferSize);
|
||||||
|
|
||||||
virtual void UnMap(UInt_64 offset, UInt_64 frames);
|
|
||||||
|
|
||||||
AudioDeviceType GetType() const;
|
AudioDeviceType GetType() const;
|
||||||
|
|
||||||
@ -89,7 +84,7 @@ namespace ehs
|
|||||||
|
|
||||||
UInt_64 GetMaxFrames() const;
|
UInt_64 GetMaxFrames() const;
|
||||||
|
|
||||||
bool IsStreaming() const;
|
virtual bool IsStreaming() const;
|
||||||
|
|
||||||
virtual bool IsValid() const;
|
virtual bool IsValid() const;
|
||||||
|
|
||||||
|
@ -1,216 +0,0 @@
|
|||||||
#include "ehs/io/audio/AudioDevice_ALSA.h"
|
|
||||||
#include "ehs/EHS.h"
|
|
||||||
#include "ehs/Log.h"
|
|
||||||
#include "ehs/system/Semaphore.h"
|
|
||||||
|
|
||||||
#include <spa/utils/list.h>
|
|
||||||
#include <spa/utils/result.h>
|
|
||||||
#include <spa/utils/dict.h>
|
|
||||||
|
|
||||||
#include "ehs/io/audio/AudioDevice.h"
|
|
||||||
|
|
||||||
namespace ehs
|
|
||||||
{
|
|
||||||
Array<AudioDevice> AudioDevice::devices;
|
|
||||||
|
|
||||||
void AudioDevice::RegistryEventGlobal(void *user_data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props)
|
|
||||||
{
|
|
||||||
const Str_8 mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
|
|
||||||
|
|
||||||
if (mediaClass.Size() && (mediaClass == "Audio/Sink" || mediaClass == "Audio/Source"))
|
|
||||||
{
|
|
||||||
AudioDevice device;
|
|
||||||
|
|
||||||
if (mediaClass == "Audio/Sink")
|
|
||||||
device.type = AudioDeviceType::OUTPUT;
|
|
||||||
else if (mediaClass == "Audio/Source")
|
|
||||||
device.type = AudioDeviceType::INPUT;
|
|
||||||
|
|
||||||
device.id = id;
|
|
||||||
device.name = spa_dict_lookup(props, PW_KEY_NODE_NAME);
|
|
||||||
|
|
||||||
EHS_LOG_INT(LogType::INFO, 1, "\nDevice Name: " + device.name + "\nId: " + Str_8::FromNum(device.id));
|
|
||||||
|
|
||||||
const pw_metadata *metadata = pw_core_get_metadata();
|
|
||||||
|
|
||||||
devices.Push(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioDevice::RegistryEventGlobalRemove(void *user_data, UInt_32 id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice::~AudioDevice()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice::AudioDevice()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice::AudioDevice(AudioDevice&& device) noexcept
|
|
||||||
: BaseAudioDevice(device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice::AudioDevice(const AudioDevice& device)
|
|
||||||
: BaseAudioDevice(device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice& AudioDevice::operator=(AudioDevice&& device) noexcept
|
|
||||||
{
|
|
||||||
if (this == &device)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
BaseAudioDevice::operator=(device);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice& AudioDevice::operator=(const AudioDevice& device)
|
|
||||||
{
|
|
||||||
if (this == &device)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
BaseAudioDevice::operator=(device);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioDevice::Release()
|
|
||||||
{
|
|
||||||
if (!IsValid())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioDevice::OpenStream()
|
|
||||||
{
|
|
||||||
if (streaming)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pw_init(nullptr, nullptr);
|
|
||||||
|
|
||||||
loop = pw_loop_new(nullptr);
|
|
||||||
context = pw_context_new(loop, nullptr, 0);
|
|
||||||
core = pw_context_connect(context, nullptr, 0);
|
|
||||||
|
|
||||||
spa_audio_info_raw info = {
|
|
||||||
.format = SPA_AUDIO_FORMAT_F32,
|
|
||||||
.rate = 48000,
|
|
||||||
.channels = 2,
|
|
||||||
.position = {
|
|
||||||
SPA_AUDIO_CHANNEL_FL,
|
|
||||||
SPA_AUDIO_CHANNEL_FR,
|
|
||||||
SPA_AUDIO_CHANNEL_FC,
|
|
||||||
SPA_AUDIO_CHANNEL_LFE,
|
|
||||||
SPA_AUDIO_CHANNEL_SL,
|
|
||||||
SPA_AUDIO_CHANNEL_SR,
|
|
||||||
SPA_AUDIO_CHANNEL_RL,
|
|
||||||
SPA_AUDIO_CHANNEL_RR
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pw_properties *props = pw_properties_new(
|
|
||||||
PW_KEY_MEDIA_TYPE, "Audio",
|
|
||||||
PW_KEY_MEDIA_CATEGORY, "Playback",
|
|
||||||
PW_KEY_MEDIA_ROLE, "Game",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
spa_pod_builder b = {};
|
|
||||||
Byte buffer[1024];
|
|
||||||
|
|
||||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
const spa_pod *pod[] = {spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info)};
|
|
||||||
|
|
||||||
pw_stream_connect(
|
|
||||||
stream,
|
|
||||||
PW_DIRECTION_OUTPUT,
|
|
||||||
PW_ID_ANY,
|
|
||||||
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS),
|
|
||||||
pod,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
streaming = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioDevice::CloseStream()
|
|
||||||
{
|
|
||||||
if (!streaming)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pw_stream_destroy(stream);
|
|
||||||
pw_core_disconnect(core);
|
|
||||||
pw_context_destroy(context);
|
|
||||||
pw_loop_destroy(loop);
|
|
||||||
pw_deinit();
|
|
||||||
|
|
||||||
streaming = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt_64 AudioDevice::SendStream(void *data, const UInt_64 size)
|
|
||||||
{
|
|
||||||
while (pw_loop_iterate(loop, 0));
|
|
||||||
|
|
||||||
if (pw_stream_get_state(stream, nullptr) != PW_STREAM_STATE_STREAMING)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pw_buffer *buf = pw_stream_dequeue_buffer(stream);
|
|
||||||
if (!buf)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
UInt_64 out = 0;
|
|
||||||
|
|
||||||
spa_data &result = buf->buffer->datas[0];
|
|
||||||
|
|
||||||
if (size > result.maxsize)
|
|
||||||
out = result.maxsize;
|
|
||||||
else
|
|
||||||
out = size;
|
|
||||||
|
|
||||||
Util::Copy(result.data, data, out);
|
|
||||||
|
|
||||||
pw_stream_queue_buffer(stream, buf);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioDevice::IsValid() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDevice AudioDevice::GetDefault(const AudioDeviceType type)
|
|
||||||
{
|
|
||||||
pw_init(nullptr, nullptr);
|
|
||||||
|
|
||||||
pw_loop *loop = pw_loop_new(nullptr);
|
|
||||||
pw_context *context = pw_context_new(loop, nullptr, 0);
|
|
||||||
pw_core *core = pw_context_connect(context, nullptr, 0);
|
|
||||||
pw_registry *registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0);
|
|
||||||
spa_hook listener = {};
|
|
||||||
|
|
||||||
constexpr pw_registry_events events = {
|
|
||||||
.version = PW_VERSION_REGISTRY_EVENTS,
|
|
||||||
.global = RegistryEventGlobal,
|
|
||||||
.global_remove = RegistryEventGlobalRemove
|
|
||||||
};
|
|
||||||
|
|
||||||
pw_registry_add_listener(registry, &listener, &events, nullptr);
|
|
||||||
|
|
||||||
while (pw_loop_iterate(loop, 10));
|
|
||||||
|
|
||||||
constexpr pw_metadata_events
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<AudioDevice> AudioDevice::Get(const AudioDeviceType type, const AudioDeviceState state)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
409
src/io/audio/AudioDevice_PW.cpp
Normal file
409
src/io/audio/AudioDevice_PW.cpp
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
#include "ehs/io/audio/AudioDevice_PW.h"
|
||||||
|
#include "ehs/EHS.h"
|
||||||
|
#include "ehs/Log.h"
|
||||||
|
#include "ehs/system/Semaphore.h"
|
||||||
|
|
||||||
|
#include <spa/utils/result.h>
|
||||||
|
#include <spa/utils/dict.h>
|
||||||
|
#include <spa/buffer/buffer.h>
|
||||||
|
#include <spa/param/latency-utils.h>
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
Array<AudioDevice> AudioDevice::devices;
|
||||||
|
|
||||||
|
void AudioDevice::RegistryEventGlobal(void *data, const UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props)
|
||||||
|
{
|
||||||
|
if (Str_8::Cmp(type, PW_TYPE_INTERFACE_Node))
|
||||||
|
{
|
||||||
|
const Str_8 mediaClass = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
|
||||||
|
if (mediaClass.Size() && (mediaClass == "Audio/Sink" || mediaClass == "Audio/Source"))
|
||||||
|
{
|
||||||
|
AudioDevice device;
|
||||||
|
|
||||||
|
if (mediaClass == "Audio/Sink")
|
||||||
|
device.type = AudioDeviceType::OUTPUT;
|
||||||
|
else if (mediaClass == "Audio/Source")
|
||||||
|
device.type = AudioDeviceType::INPUT;
|
||||||
|
|
||||||
|
device.id = id;
|
||||||
|
device.name = spa_dict_lookup(props, PW_KEY_NODE_NAME);
|
||||||
|
|
||||||
|
EHS_LOG_INT(LogType::INFO, 1, "\nDevice Name: " + device.name + "\nId: " + Str_8::FromNum(device.id));
|
||||||
|
|
||||||
|
devices.Push(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::RegistryEventGlobalRemove(void *data, UInt_32 id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::OnParamChanged(void *data, UInt_32 id, const spa_pod *param)
|
||||||
|
{
|
||||||
|
if (!param)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (id == SPA_PARAM_Buffers)
|
||||||
|
{
|
||||||
|
AudioDevice *device = (AudioDevice *)data;
|
||||||
|
|
||||||
|
spa_pod_object *obj = (spa_pod_object *)param;
|
||||||
|
spa_pod_prop *prop;
|
||||||
|
|
||||||
|
SPA_POD_OBJECT_FOREACH(obj, prop)
|
||||||
|
{
|
||||||
|
if (prop->key == SPA_PARAM_BUFFERS_size)
|
||||||
|
{
|
||||||
|
spa_pod_get_int(&prop->value, (int32_t *)&device->maxFrames);
|
||||||
|
device->maxFrames = device->maxFrames / device->byteDepth / device->channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice::~AudioDevice()
|
||||||
|
{
|
||||||
|
if (!IsStreaming())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (output)
|
||||||
|
{
|
||||||
|
pw_stream_disconnect(output);
|
||||||
|
pw_stream_destroy(output);
|
||||||
|
output = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
pw_stream_disconnect(input);
|
||||||
|
pw_stream_destroy(input);
|
||||||
|
input = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_core_disconnect(core);
|
||||||
|
core = nullptr;
|
||||||
|
|
||||||
|
pw_context_destroy(context);
|
||||||
|
context = nullptr;
|
||||||
|
|
||||||
|
pw_loop_destroy(loop);
|
||||||
|
loop = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice::AudioDevice()
|
||||||
|
: id(0), loop(nullptr), context(nullptr), core(nullptr), input(nullptr), output(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice::AudioDevice(AudioDevice&& device) noexcept
|
||||||
|
: BaseAudioDevice(device), id(device.id), name((Str_8 &&)device.name), loop(device.loop),
|
||||||
|
context(device.context), core(device.core), input(device.input), output(device.output)
|
||||||
|
{
|
||||||
|
device.id = 0;
|
||||||
|
device.loop = nullptr;
|
||||||
|
device.context = nullptr;
|
||||||
|
device.core = nullptr;
|
||||||
|
device.input = nullptr;
|
||||||
|
device.output = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice::AudioDevice(const AudioDevice& device)
|
||||||
|
: BaseAudioDevice(device), id(device.id), name(device.name), loop(nullptr), context(nullptr), core(nullptr),
|
||||||
|
input(nullptr), output(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice& AudioDevice::operator=(AudioDevice&& device) noexcept
|
||||||
|
{
|
||||||
|
if (this == &device)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
BaseAudioDevice::operator=(device);
|
||||||
|
|
||||||
|
id = device.id;
|
||||||
|
name = (Str_8 &&)device.name;
|
||||||
|
loop = device.loop;
|
||||||
|
context = device.context;
|
||||||
|
core = device.core;
|
||||||
|
input = device.input;
|
||||||
|
output = device.output;
|
||||||
|
|
||||||
|
device.id = 0;
|
||||||
|
device.loop = nullptr;
|
||||||
|
device.context = nullptr;
|
||||||
|
device.core = nullptr;
|
||||||
|
device.input = nullptr;
|
||||||
|
device.output = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice& AudioDevice::operator=(const AudioDevice& device)
|
||||||
|
{
|
||||||
|
if (this == &device)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
BaseAudioDevice::operator=(device);
|
||||||
|
|
||||||
|
id = device.id;
|
||||||
|
name = device.name;
|
||||||
|
loop = nullptr;
|
||||||
|
context = nullptr;
|
||||||
|
core = nullptr;
|
||||||
|
input = nullptr;
|
||||||
|
output = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::OpenStream()
|
||||||
|
{
|
||||||
|
if (!IsValid() || IsStreaming())
|
||||||
|
return;
|
||||||
|
|
||||||
|
loop = pw_loop_new(nullptr);
|
||||||
|
context = pw_context_new(loop, nullptr, 0);
|
||||||
|
core = pw_context_connect(context, nullptr, 0);
|
||||||
|
|
||||||
|
spa_audio_info_raw info = {
|
||||||
|
.format = SPA_AUDIO_FORMAT_F32,
|
||||||
|
.rate = GetSampleRate(),
|
||||||
|
.channels = GetChannels(),
|
||||||
|
.position = {
|
||||||
|
SPA_AUDIO_CHANNEL_FL,
|
||||||
|
SPA_AUDIO_CHANNEL_FR,
|
||||||
|
SPA_AUDIO_CHANNEL_FC,
|
||||||
|
SPA_AUDIO_CHANNEL_LFE,
|
||||||
|
SPA_AUDIO_CHANNEL_SL,
|
||||||
|
SPA_AUDIO_CHANNEL_SR,
|
||||||
|
SPA_AUDIO_CHANNEL_RL,
|
||||||
|
SPA_AUDIO_CHANNEL_RR
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pw_properties *props = pw_properties_new(
|
||||||
|
PW_KEY_MEDIA_TYPE, "Audio",
|
||||||
|
PW_KEY_MEDIA_CATEGORY, GetCategory(),
|
||||||
|
PW_KEY_MEDIA_ROLE, "Game",
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
spa_pod_builder b = {};
|
||||||
|
Byte buffer[1024];
|
||||||
|
|
||||||
|
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
const spa_pod *pod[] = {spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &info)};
|
||||||
|
|
||||||
|
if (GetType() == AudioDeviceType::INPUT || GetType() == AudioDeviceType::ALL)
|
||||||
|
{
|
||||||
|
input = pw_stream_new(core, "", props);
|
||||||
|
if (!input)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 1, "Failed to create input stream for audio device.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_stream_connect(
|
||||||
|
output,
|
||||||
|
PW_DIRECTION_INPUT,
|
||||||
|
id,
|
||||||
|
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS),
|
||||||
|
pod,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetType() == AudioDeviceType::OUTPUT || GetType() == AudioDeviceType::ALL)
|
||||||
|
{
|
||||||
|
output = pw_stream_new(core, "", props);
|
||||||
|
if (!output)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 1, "Failed to create output stream for audio device.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_stream_connect(
|
||||||
|
output,
|
||||||
|
PW_DIRECTION_OUTPUT,
|
||||||
|
id,
|
||||||
|
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS),
|
||||||
|
pod,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr pw_stream_events streamEvents = {
|
||||||
|
.version = PW_VERSION_STREAM_EVENTS,
|
||||||
|
.param_changed = OnParamChanged
|
||||||
|
};
|
||||||
|
|
||||||
|
spa_hook streamListener = {};
|
||||||
|
pw_stream_add_listener(output, &streamListener, &streamEvents, this);
|
||||||
|
|
||||||
|
EHS_LOG_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::CloseStream()
|
||||||
|
{
|
||||||
|
if (!IsStreaming())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (output)
|
||||||
|
{
|
||||||
|
pw_stream_disconnect(output);
|
||||||
|
pw_stream_destroy(output);
|
||||||
|
output = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
pw_stream_disconnect(input);
|
||||||
|
pw_stream_destroy(input);
|
||||||
|
input = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_core_disconnect(core);
|
||||||
|
core = nullptr;
|
||||||
|
|
||||||
|
pw_context_destroy(context);
|
||||||
|
context = nullptr;
|
||||||
|
|
||||||
|
pw_loop_destroy(loop);
|
||||||
|
loop = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_64 AudioDevice::SendStream(const void *data, const UInt_64 size)
|
||||||
|
{
|
||||||
|
if (GetType() != AudioDeviceType::OUTPUT && GetType() != AudioDeviceType::ALL)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 0, "You can only send an audio stream on an output audio device.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_loop_iterate(loop, 0);
|
||||||
|
|
||||||
|
if (pw_stream_get_state(output, nullptr) != PW_STREAM_STATE_STREAMING)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pw_buffer *buf = pw_stream_dequeue_buffer(output);
|
||||||
|
if (!buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
UInt_64 out = 0;
|
||||||
|
|
||||||
|
spa_data &result = buf->buffer->datas[0];
|
||||||
|
|
||||||
|
if (size > result.maxsize)
|
||||||
|
out = result.maxsize;
|
||||||
|
else
|
||||||
|
out = size;
|
||||||
|
|
||||||
|
Util::Copy(result.data, data, out);
|
||||||
|
|
||||||
|
pw_stream_queue_buffer(output, buf);
|
||||||
|
|
||||||
|
EHS_LOG_SUCCESS();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_64 AudioDevice::ReceiveStream(void *data, const UInt_64 size)
|
||||||
|
{
|
||||||
|
if (GetType() != AudioDeviceType::INPUT && GetType() != AudioDeviceType::ALL)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 0, "You can only send an audio stream on an input audio device.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw_loop_iterate(loop, 0);
|
||||||
|
|
||||||
|
if (pw_stream_get_state(input, nullptr) != PW_STREAM_STATE_STREAMING)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pw_buffer *buf = pw_stream_dequeue_buffer(input);
|
||||||
|
if (!buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spa_data &result = buf->buffer->datas[0];
|
||||||
|
|
||||||
|
UInt_64 in;
|
||||||
|
if (result.chunk->size <= size)
|
||||||
|
in = result.chunk->size;
|
||||||
|
else
|
||||||
|
in = size;
|
||||||
|
|
||||||
|
Util::Copy(data, result.data, in);
|
||||||
|
|
||||||
|
pw_stream_queue_buffer(input, buf);
|
||||||
|
|
||||||
|
EHS_LOG_SUCCESS();
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioDevice::IsStreaming() const
|
||||||
|
{
|
||||||
|
return loop && context && core && (input || output);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioDevice::IsValid() const
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice AudioDevice::GetDefault(const AudioDeviceType type)
|
||||||
|
{
|
||||||
|
pw_init(nullptr, nullptr);
|
||||||
|
|
||||||
|
AudioDevice result;
|
||||||
|
result.type = type;
|
||||||
|
result.id = PW_ID_ANY;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<AudioDevice> AudioDevice::Get(const AudioDeviceType type, const AudioDeviceState state)
|
||||||
|
{
|
||||||
|
pw_init(nullptr, nullptr);
|
||||||
|
|
||||||
|
pw_loop *loop = pw_loop_new(nullptr);
|
||||||
|
pw_context *context = pw_context_new(loop, nullptr, 0);
|
||||||
|
pw_core *core = pw_context_connect(context, nullptr, 0);
|
||||||
|
pw_registry *registry = pw_core_get_registry(core, PW_VERSION_REGISTRY, 0);
|
||||||
|
spa_hook listener = {};
|
||||||
|
|
||||||
|
static constexpr pw_registry_events events = {
|
||||||
|
.version = PW_VERSION_REGISTRY_EVENTS,
|
||||||
|
.global = RegistryEventGlobal,
|
||||||
|
.global_remove = RegistryEventGlobalRemove
|
||||||
|
};
|
||||||
|
|
||||||
|
pw_registry_add_listener(registry, &listener, &events, registry);
|
||||||
|
|
||||||
|
while (pw_loop_iterate(loop, 10));
|
||||||
|
|
||||||
|
pw_core_disconnect(core);
|
||||||
|
pw_context_destroy(context);
|
||||||
|
pw_loop_destroy(loop);
|
||||||
|
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 AudioDevice::GetCategory() const
|
||||||
|
{
|
||||||
|
switch (GetType())
|
||||||
|
{
|
||||||
|
case AudioDeviceType::INPUT:
|
||||||
|
return "Capture";
|
||||||
|
case AudioDeviceType::OUTPUT:
|
||||||
|
return "Playback";
|
||||||
|
case AudioDeviceType::ALL:
|
||||||
|
return "Duplex";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,14 +3,14 @@
|
|||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
BaseAudioDevice::BaseAudioDevice()
|
BaseAudioDevice::BaseAudioDevice()
|
||||||
: type(AudioDeviceType::ALL), dataType(DataType::SINT_8), bitDepth(0), sampleRate(0), channels(0),
|
: type(AudioDeviceType::ALL), dataType(DataType::SINT_8), byteDepth(0), sampleRate(0), channels(0),
|
||||||
period(20000), latency(150000), maxFrames(0), streaming(false)
|
period(20000), latency(150000), maxFrames(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseAudioDevice::BaseAudioDevice(const BaseAudioDevice& device)
|
BaseAudioDevice::BaseAudioDevice(const BaseAudioDevice& device)
|
||||||
: type(device.type), dataType(device.dataType), bitDepth(device.bitDepth), sampleRate(device.sampleRate),
|
: type(device.type), dataType(device.dataType), byteDepth(device.byteDepth), sampleRate(device.sampleRate),
|
||||||
channels(device.channels), period(device.period), latency(device.latency), maxFrames(0), streaming(false)
|
channels(device.channels), period(device.period), latency(device.latency), maxFrames(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,21 +21,16 @@ namespace ehs
|
|||||||
|
|
||||||
type = device.type;
|
type = device.type;
|
||||||
dataType = device.dataType;
|
dataType = device.dataType;
|
||||||
bitDepth = device.bitDepth;
|
byteDepth = device.byteDepth;
|
||||||
sampleRate = device.sampleRate;
|
sampleRate = device.sampleRate;
|
||||||
channels = device.channels;
|
channels = device.channels;
|
||||||
period = device.period;
|
period = device.period;
|
||||||
latency = device.latency;
|
latency = device.latency;
|
||||||
maxFrames = device.maxFrames;
|
maxFrames = device.maxFrames;
|
||||||
streaming = false;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseAudioDevice::Release()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseAudioDevice::OpenStream()
|
void BaseAudioDevice::OpenStream()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -44,37 +39,43 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt_64 BaseAudioDevice::SendStream(void *data, UInt_64 size)
|
UInt_64 BaseAudioDevice::SendStream(const void *data, const UInt_64 size)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt_64 BaseAudioDevice::GetAvailFrames() const
|
UInt_64 BaseAudioDevice::ReceiveStream(void *data, const UInt_64 size)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte* BaseAudioDevice::Map(UInt_64* offset, UInt_64* frames)
|
void BaseAudioDevice::BridgeStreams(const UInt_64 bufferSize)
|
||||||
{
|
{
|
||||||
return nullptr;
|
Byte* buffer = new Byte[bufferSize];
|
||||||
|
|
||||||
|
UInt_64 result = ReceiveStream(buffer, bufferSize);
|
||||||
|
while (result < bufferSize)
|
||||||
|
result += ReceiveStream(&buffer[result], bufferSize - result);
|
||||||
|
|
||||||
|
result -= SendStream(buffer, result);
|
||||||
|
while (result)
|
||||||
|
result -= SendStream(&buffer[bufferSize - result], result);
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseAudioDevice::UnMap(const UInt_64 offset, const UInt_64 frames)
|
AudioDeviceType BaseAudioDevice::GetType() const
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioDeviceType BaseAudioDevice::GetType() const
|
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseAudioDevice::SetDataType(const DataType newDataType)
|
void BaseAudioDevice::SetDataType(const DataType newDataType)
|
||||||
{
|
{
|
||||||
if (streaming)
|
if (IsStreaming())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dataType = newDataType;
|
dataType = newDataType;
|
||||||
bitDepth = ToBitDepth(newDataType);
|
byteDepth = ToByteDepth(newDataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataType BaseAudioDevice::GetDataType() const
|
DataType BaseAudioDevice::GetDataType() const
|
||||||
@ -84,17 +85,17 @@ namespace ehs
|
|||||||
|
|
||||||
UInt_8 BaseAudioDevice::GetByteDepth() const
|
UInt_8 BaseAudioDevice::GetByteDepth() const
|
||||||
{
|
{
|
||||||
return bitDepth / 8;
|
return byteDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt_16 BaseAudioDevice::GetBitDepth() const
|
UInt_16 BaseAudioDevice::GetBitDepth() const
|
||||||
{
|
{
|
||||||
return bitDepth;
|
return byteDepth * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseAudioDevice::SetSampleRate(const UInt_32 newSampleRate)
|
void BaseAudioDevice::SetSampleRate(const UInt_32 newSampleRate)
|
||||||
{
|
{
|
||||||
if (streaming)
|
if (IsStreaming())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sampleRate = newSampleRate;
|
sampleRate = newSampleRate;
|
||||||
@ -107,7 +108,7 @@ namespace ehs
|
|||||||
|
|
||||||
void BaseAudioDevice::SetChannels(const UInt_32 newChannels)
|
void BaseAudioDevice::SetChannels(const UInt_32 newChannels)
|
||||||
{
|
{
|
||||||
if (streaming)
|
if (IsStreaming())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
channels = newChannels;
|
channels = newChannels;
|
||||||
@ -120,12 +121,12 @@ namespace ehs
|
|||||||
|
|
||||||
UInt_32 BaseAudioDevice::GetFrameSize() const
|
UInt_32 BaseAudioDevice::GetFrameSize() const
|
||||||
{
|
{
|
||||||
return bitDepth / 8 * channels;
|
return byteDepth * channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseAudioDevice::SetPeriod(const UInt_32 newPeriod)
|
void BaseAudioDevice::SetPeriod(const UInt_32 newPeriod)
|
||||||
{
|
{
|
||||||
if (streaming)
|
if (IsStreaming())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
period = newPeriod;
|
period = newPeriod;
|
||||||
@ -138,7 +139,7 @@ namespace ehs
|
|||||||
|
|
||||||
void BaseAudioDevice::SetLatency(const UInt_32 newLatency)
|
void BaseAudioDevice::SetLatency(const UInt_32 newLatency)
|
||||||
{
|
{
|
||||||
if (streaming)
|
if (IsStreaming())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
latency = newLatency;
|
latency = newLatency;
|
||||||
@ -156,7 +157,7 @@ namespace ehs
|
|||||||
|
|
||||||
bool BaseAudioDevice::IsStreaming() const
|
bool BaseAudioDevice::IsStreaming() const
|
||||||
{
|
{
|
||||||
return streaming;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseAudioDevice::IsValid() const
|
bool BaseAudioDevice::IsValid() const
|
||||||
|
Loading…
Reference in New Issue
Block a user