327 lines
7.6 KiB
C
327 lines
7.6 KiB
C
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "openmpt/all/BuildSettings.hpp"
|
||
|
|
||
|
#include "NativeSoundDevice.h"
|
||
|
|
||
|
#include "openmpt/sounddevice/SoundDevice.hpp"
|
||
|
|
||
|
#ifdef MPT_WITH_NLOHMANNJSON
|
||
|
|
||
|
// https://github.com/nlohmann/json/issues/1204
|
||
|
#if MPT_COMPILER_MSVC
|
||
|
#pragma warning(push)
|
||
|
#pragma warning(disable:4127) // conditional expression is constant
|
||
|
#endif // MPT_COMPILER_MSVC
|
||
|
#include "mpt/json/json.hpp"
|
||
|
#if MPT_COMPILER_MSVC
|
||
|
#pragma warning(pop)
|
||
|
#endif // MPT_COMPILER_MSVC
|
||
|
|
||
|
#endif // MPT_WITH_NLOHMANNJSON
|
||
|
|
||
|
|
||
|
|
||
|
OPENMPT_NAMESPACE_BEGIN
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef MPT_WITH_NLOHMANNJSON
|
||
|
|
||
|
inline void to_json(nlohmann::json &j, const SampleFormat &val)
|
||
|
{
|
||
|
j = SampleFormat::ToInt(val);
|
||
|
}
|
||
|
inline void from_json(const nlohmann::json &j, SampleFormat &val)
|
||
|
{
|
||
|
val = SampleFormat::FromInt(j);
|
||
|
}
|
||
|
|
||
|
namespace SoundDevice
|
||
|
{
|
||
|
|
||
|
inline void to_json(nlohmann::json &j, const SoundDevice::ChannelMapping &val)
|
||
|
{
|
||
|
j = val.ToUString();
|
||
|
}
|
||
|
inline void from_json(const nlohmann::json &j, SoundDevice::ChannelMapping &val)
|
||
|
{
|
||
|
val = SoundDevice::ChannelMapping::FromString(j);
|
||
|
}
|
||
|
|
||
|
inline void to_json(nlohmann::json &j, const SoundDevice::Info::Default &val)
|
||
|
{
|
||
|
j = static_cast<int>(val);
|
||
|
}
|
||
|
inline void from_json(const nlohmann::json &j, SoundDevice::Info::Default &val)
|
||
|
{
|
||
|
val = static_cast<SoundDevice::Info::Default>(static_cast<int>(j));
|
||
|
}
|
||
|
} // namespace SoundDevice
|
||
|
|
||
|
|
||
|
|
||
|
namespace SoundDevice
|
||
|
{
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info::ManagerFlags
|
||
|
,defaultFor
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info::Flags
|
||
|
,usability
|
||
|
,level
|
||
|
,compatible
|
||
|
,api
|
||
|
,io
|
||
|
,mixing
|
||
|
,implementor
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Info
|
||
|
,type
|
||
|
,internalID
|
||
|
,name
|
||
|
,apiName
|
||
|
,apiPath
|
||
|
,default_
|
||
|
,useNameAsIdentifier
|
||
|
,managerFlags
|
||
|
,flags
|
||
|
,extraData
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::AppInfo
|
||
|
,Name
|
||
|
,BoostedThreadPriorityXP
|
||
|
,BoostedThreadMMCSSClassVista
|
||
|
,BoostedThreadRealtimePosix
|
||
|
,BoostedThreadNicenessPosix
|
||
|
,BoostedThreadRtprioPosix
|
||
|
,MaskDriverCrashes
|
||
|
,AllowDeferredProcessing
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Settings
|
||
|
,Latency
|
||
|
,UpdateInterval
|
||
|
,Samplerate
|
||
|
,Channels
|
||
|
,InputChannels
|
||
|
,sampleFormat
|
||
|
,ExclusiveMode
|
||
|
,BoostThreadPriority
|
||
|
,KeepDeviceRunning
|
||
|
,UseHardwareTiming
|
||
|
,DitherType
|
||
|
,InputSourceID
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Caps
|
||
|
,Available
|
||
|
,CanUpdateInterval
|
||
|
,CanSampleFormat
|
||
|
,CanExclusiveMode
|
||
|
,CanBoostThreadPriority
|
||
|
,CanKeepDeviceRunning
|
||
|
,CanUseHardwareTiming
|
||
|
,CanChannelMapping
|
||
|
,CanInput
|
||
|
,HasNamedInputSources
|
||
|
,CanDriverPanel
|
||
|
,HasInternalDither
|
||
|
,ExclusiveModeDescription
|
||
|
,LatencyMin
|
||
|
,LatencyMax
|
||
|
,UpdateIntervalMin
|
||
|
,UpdateIntervalMax
|
||
|
,DefaultSettings
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::DynamicCaps
|
||
|
,currentSampleRate
|
||
|
,supportedSampleRates
|
||
|
,supportedExclusiveSampleRates
|
||
|
,supportedSampleFormats
|
||
|
,supportedExclusiveModeSampleFormats
|
||
|
,channelNames
|
||
|
,inputSourceNames
|
||
|
)
|
||
|
|
||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SoundDevice::Statistics
|
||
|
,InstantaneousLatency
|
||
|
,LastUpdateInterval
|
||
|
,text
|
||
|
)
|
||
|
|
||
|
} // namespace SoundDevice
|
||
|
|
||
|
|
||
|
|
||
|
template <typename Tdst, typename Tsrc>
|
||
|
struct json_cast_impl
|
||
|
{
|
||
|
Tdst operator () (const Tsrc &src);
|
||
|
};
|
||
|
|
||
|
|
||
|
template <typename Tdst, typename Tsrc>
|
||
|
Tdst json_cast(const Tsrc &src)
|
||
|
{
|
||
|
return json_cast_impl<Tdst, Tsrc>()(src);
|
||
|
}
|
||
|
|
||
|
|
||
|
template <typename Tsrc>
|
||
|
struct json_cast_impl<nlohmann::json, Tsrc>
|
||
|
{
|
||
|
nlohmann::json operator () (const Tsrc &src)
|
||
|
{
|
||
|
return static_cast<nlohmann::json>(src);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename Tdst>
|
||
|
struct json_cast_impl<Tdst, nlohmann::json>
|
||
|
{
|
||
|
Tdst operator () (const nlohmann::json &src)
|
||
|
{
|
||
|
return src.get<Tdst>();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename Tsrc>
|
||
|
struct json_cast_impl<std::string, Tsrc>
|
||
|
{
|
||
|
std::string operator () (const Tsrc &src)
|
||
|
{
|
||
|
return json_cast<nlohmann::json>(src).dump(4);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename Tdst>
|
||
|
struct json_cast_impl<Tdst, std::string>
|
||
|
{
|
||
|
Tdst operator () (const std::string &str)
|
||
|
{
|
||
|
return json_cast<Tdst>(nlohmann::json::parse(str));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif // MPT_WITH_NLOHMANNJSON
|
||
|
|
||
|
|
||
|
|
||
|
namespace C {
|
||
|
|
||
|
static_assert(sizeof(OpenMPT_SoundDevice_StreamPosition) % 8 == 0);
|
||
|
inline OpenMPT_SoundDevice_StreamPosition encode(SoundDevice::StreamPosition src) {
|
||
|
OpenMPT_SoundDevice_StreamPosition dst;
|
||
|
MemsetZero(dst);
|
||
|
dst.Frames = src.Frames;
|
||
|
dst.Seconds = src.Seconds;
|
||
|
return dst;
|
||
|
}
|
||
|
inline SoundDevice::StreamPosition decode(OpenMPT_SoundDevice_StreamPosition src) {
|
||
|
SoundDevice::StreamPosition dst;
|
||
|
dst.Frames = src.Frames;
|
||
|
dst.Seconds = src.Seconds;
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
static_assert(sizeof(OpenMPT_SoundDevice_TimeInfo) % 8 == 0);
|
||
|
inline OpenMPT_SoundDevice_TimeInfo encode(SoundDevice::TimeInfo src) {
|
||
|
OpenMPT_SoundDevice_TimeInfo dst;
|
||
|
MemsetZero(dst);
|
||
|
dst.SyncPointStreamFrames = src.SyncPointStreamFrames;
|
||
|
dst.SyncPointSystemTimestamp = src.SyncPointSystemTimestamp;
|
||
|
dst.Speed = src.Speed;
|
||
|
dst.RenderStreamPositionBefore = encode(src.RenderStreamPositionBefore);
|
||
|
dst.RenderStreamPositionAfter = encode(src.RenderStreamPositionAfter);
|
||
|
dst.Latency = src.Latency;
|
||
|
return dst;
|
||
|
}
|
||
|
inline SoundDevice::TimeInfo decode(OpenMPT_SoundDevice_TimeInfo src) {
|
||
|
SoundDevice::TimeInfo dst;
|
||
|
dst.SyncPointStreamFrames = src.SyncPointStreamFrames;
|
||
|
dst.SyncPointSystemTimestamp = src.SyncPointSystemTimestamp;
|
||
|
dst.Speed = src.Speed;
|
||
|
dst.RenderStreamPositionBefore = decode(src.RenderStreamPositionBefore);
|
||
|
dst.RenderStreamPositionAfter = decode(src.RenderStreamPositionAfter);
|
||
|
dst.Latency = src.Latency;
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
static_assert(sizeof(OpenMPT_SoundDevice_Flags) % 8 == 0);
|
||
|
inline OpenMPT_SoundDevice_Flags encode(SoundDevice::Flags src) {
|
||
|
OpenMPT_SoundDevice_Flags dst;
|
||
|
MemsetZero(dst);
|
||
|
dst.WantsClippedOutput = src.WantsClippedOutput;
|
||
|
return dst;
|
||
|
}
|
||
|
inline SoundDevice::Flags decode(OpenMPT_SoundDevice_Flags src) {
|
||
|
SoundDevice::Flags dst;
|
||
|
dst.WantsClippedOutput = src.WantsClippedOutput;
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
static_assert(sizeof(OpenMPT_SoundDevice_BufferFormat) % 8 == 0);
|
||
|
inline OpenMPT_SoundDevice_BufferFormat encode(SoundDevice::BufferFormat src) {
|
||
|
OpenMPT_SoundDevice_BufferFormat dst;
|
||
|
MemsetZero(dst);
|
||
|
dst.Samplerate = src.Samplerate;
|
||
|
dst.Channels = src.Channels;
|
||
|
dst.InputChannels = src.InputChannels;
|
||
|
dst.sampleFormat = SampleFormat::ToInt(src.sampleFormat);
|
||
|
dst.WantsClippedOutput = src.WantsClippedOutput;
|
||
|
dst.DitherType = src.DitherType;
|
||
|
return dst;
|
||
|
}
|
||
|
inline SoundDevice::BufferFormat decode(OpenMPT_SoundDevice_BufferFormat src) {
|
||
|
SoundDevice::BufferFormat dst;
|
||
|
dst.Samplerate = src.Samplerate;
|
||
|
dst.Channels = src.Channels;
|
||
|
dst.InputChannels = src.InputChannels;
|
||
|
dst.sampleFormat = SampleFormat::FromInt(src.sampleFormat);
|
||
|
dst.WantsClippedOutput = src.WantsClippedOutput;
|
||
|
dst.DitherType = src.DitherType;
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
static_assert(sizeof(OpenMPT_SoundDevice_BufferAttributes) % 8 == 0);
|
||
|
inline OpenMPT_SoundDevice_BufferAttributes encode(SoundDevice::BufferAttributes src) {
|
||
|
OpenMPT_SoundDevice_BufferAttributes dst;
|
||
|
MemsetZero(dst);
|
||
|
dst.Latency = src.Latency;
|
||
|
dst.UpdateInterval = src.UpdateInterval;
|
||
|
dst.NumBuffers = src.NumBuffers;
|
||
|
return dst;
|
||
|
}
|
||
|
inline SoundDevice::BufferAttributes decode(OpenMPT_SoundDevice_BufferAttributes src) {
|
||
|
SoundDevice::BufferAttributes dst;
|
||
|
dst.Latency = src.Latency;
|
||
|
dst.UpdateInterval = src.UpdateInterval;
|
||
|
dst.NumBuffers = src.NumBuffers;
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
static_assert(sizeof(OpenMPT_SoundDevice_RequestFlags) % 8 == 0);
|
||
|
inline OpenMPT_SoundDevice_RequestFlags encode(FlagSet<SoundDevice::RequestFlags> src) {
|
||
|
OpenMPT_SoundDevice_RequestFlags dst;
|
||
|
MemsetZero(dst);
|
||
|
dst.RequestFlags = src.GetRaw();
|
||
|
return dst;
|
||
|
}
|
||
|
inline FlagSet<SoundDevice::RequestFlags> decode(OpenMPT_SoundDevice_RequestFlags src) {
|
||
|
FlagSet<SoundDevice::RequestFlags> dst;
|
||
|
dst.SetRaw(src.RequestFlags);
|
||
|
return dst;
|
||
|
}
|
||
|
|
||
|
} // namespace C
|
||
|
|
||
|
|
||
|
|
||
|
OPENMPT_NAMESPACE_END
|