Skip to content

Commit

Permalink
Windows SA: Audio/MIDI settings (#307)
Browse files Browse the repository at this point in the history
* Windows SA: Audio/MIDI settings

* Windows SA: Enable /Zc:__cplusplus

* Windows SA: Set /await:strict, attempt to fix C++ 20 build error

* Windows SA: Remove /await:strict

* Windows SA: Set CMP0149 policy to NEW

* Windows SA: Run clang-format

* Windows SA: Remove unnecessary fs::create_directories when loading autosave
  • Loading branch information
mthierman authored Sep 20, 2024
1 parent 90b16c5 commit cd3cac0
Show file tree
Hide file tree
Showing 18 changed files with 1,924 additions and 932 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

cmake_minimum_required(VERSION 3.21)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0149 NEW)
if (NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
message(STATUS "[clap-wrapper]: OSX_DEPLOYEMNT_TARGET is undefined. Setting to 10.13")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13 CACHE STRING "Minimum macOS version")
Expand Down
2 changes: 1 addition & 1 deletion cmake/shared_prologue.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(clap-wrapper-compile-options INTERFACE /utf-8)
target_compile_options(clap-wrapper-compile-options INTERFACE /utf-8 /Zc:__cplusplus)
if (${CMAKE_CXX_STANDARD} GREATER_EQUAL 20)
message(STATUS "clap-wrapper: Turning off char8_t c++20 changes")
target_compile_options(clap-wrapper-compile-options-public INTERFACE /Zc:char8_t-)
Expand Down
45 changes: 19 additions & 26 deletions cmake/wrap_standalone.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function(target_add_standalone_wrapper)
STATICALLY_LINKED_CLAP_ENTRY
HOSTED_CLAP_NAME

WIN32_ICON
WINDOWS_ICON

MACOS_EMBEDDED_CLAP_LOCATION
)
Expand All @@ -37,8 +37,8 @@ function(target_add_standalone_wrapper)
set(SA_OUTPUT_NAME ${SA_TARGET})
endif()

if (NOT DEFINED SA_WIN32_ICON)
set(SA_WIN32_ICON "")
if (NOT DEFINED SA_WINDOWS_ICON)
set(SA_WINDOWS_ICON "")
endif()

guarantee_rtaudio()
Expand Down Expand Up @@ -102,16 +102,20 @@ function(target_add_standalone_wrapper)
MACOS_EMBEDDED_CLAP_LOCATION ${SA_MACOS_EMBEDDED_CLAP_LOCATION})

elseif(WIN32 AND (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
if(NOT "${SA_WIN32_ICON}" STREQUAL "")
message(STATUS "Win32 icon found: ${SA_WIN32_ICON}")
file(WRITE "${CMAKE_BINARY_DIR}/standalone_win32.rc" "1 ICON \"standalone_win32.ico\"")
file(COPY_FILE ${SA_WIN32_ICON} "${CMAKE_BINARY_DIR}/standalone_win32.ico")
else()
message(STATUS "Win32 icon not found, using default")
guarantee_wil()

if(NOT "${SA_WINDOWS_ICON}" STREQUAL "")
file(WRITE "${CMAKE_BINARY_DIR}/generated_icons/windows_standalone_${SA_TARGET}.rc" "1 ICON \"windows_standalone_${SA_TARGET}.ico\"")
file(COPY_FILE ${SA_WINDOWS_ICON} "${CMAKE_BINARY_DIR}/generated_icons/windows_standalone_${SA_TARGET}.ico")
target_sources(${SA_TARGET} PRIVATE
"${CMAKE_BINARY_DIR}/generated_icons/windows_standalone_${SA_TARGET}.rc"
)
endif()

set_target_properties(${SA_TARGET} PROPERTIES
WIN32_EXECUTABLE TRUE
target_sources(${SA_TARGET} PRIVATE
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/wrapasstandalone_windows.cpp"
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/detail/standalone/windows/windows_standalone.cpp"
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/detail/standalone/windows/windows_standalone.manifest"
)

target_compile_definitions(${salib} PUBLIC
Expand All @@ -120,23 +124,10 @@ function(target_add_standalone_wrapper)
CLAP_WRAPPER_HAS_WIN32
)

target_sources(${SA_TARGET} PRIVATE
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/wrapasstandalone_win32.cpp"
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/detail/standalone/windows/host_window.cpp"
# "${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/detail/standalone/windows/settings_window.cpp"
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/detail/standalone/windows/helpers.cpp"
"${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/detail/standalone/windows/standalone.manifest"
set_target_properties(${SA_TARGET} PROPERTIES
WIN32_EXECUTABLE TRUE
)

guarantee_wil()
target_link_libraries(${SA_TARGET} PRIVATE base-sdk-wil)

if(NOT "${SA_WIN32_ICON}" STREQUAL "")
target_sources(${SA_TARGET} PRIVATE
"${CMAKE_BINARY_DIR}/standalone_win32.rc"
)
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_link_options(
${SA_TARGET}
Expand All @@ -151,6 +142,8 @@ function(target_add_standalone_wrapper)
)
endif()

target_link_libraries(${SA_TARGET} PRIVATE base-sdk-wil ComCtl32.Lib)

elseif(UNIX)
target_sources(${SA_TARGET} PRIVATE
${CLAP_WRAPPER_CMAKE_CURRENT_SOURCE_DIR}/src/wrapasstandalone.cpp)
Expand Down
1 change: 1 addition & 0 deletions src/detail/standalone/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ std::shared_ptr<Clap::Plugin> mainCreatePlugin(const clap_plugin_entry *ee, cons
try
{
LOG << "Trying to save default clap wrapper settings" << std::endl;
fs::create_directories(loadPath);
standaloneHost->saveStandaloneAndPluginSettings(loadPath, "defaults.clapwrapper");
}
catch (const fs::filesystem_error &e)
Expand Down
10 changes: 10 additions & 0 deletions src/detail/standalone/standalone_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ struct StandaloneHost : Clap::IHost
};
ClapWrapper::detail::shared::fixedqueue<midiChunk, 4096> midiToAudioQueue;
std::vector<std::unique_ptr<RtMidiIn>> midiIns;
uint32_t numMidiPorts{0};
std::vector<uint32_t> currentMidiPorts;
void startMIDIThread();
void stopMIDIThread();
void processMIDIEvents(double deltatime, std::vector<unsigned char> *message);
Expand All @@ -246,10 +248,15 @@ struct StandaloneHost : Clap::IHost
// Actual audio IO In standalone_host_audio.cpp
std::unique_ptr<RtAudio> rtaDac;
std::function<void(const std::string &)> displayAudioError{nullptr};
RtAudio::Api audioApi{RtAudio::Api::UNSPECIFIED};
std::string audioApiName{RtAudio::getApiName(RtAudio::Api::UNSPECIFIED)};
std::string audioApiDisplayName{RtAudio::getApiDisplayName(RtAudio::Api::UNSPECIFIED)};
unsigned int audioInputDeviceID{0}, audioOutputDeviceID{0};
bool audioInputUsed{true}, audioOutputUsed{true};
int32_t currentSampleRate{0};
uint32_t currentBufferSize{0};
void guaranteeRtAudioDAC();
void setAudioApi(RtAudio::Api api);
std::tuple<unsigned int, unsigned int, int32_t> getDefaultAudioInOutSampleRate();
void startAudioThread();
void startAudioThreadOn(unsigned int inputDeviceID, uint32_t inputChannels, bool useInput,
Expand All @@ -271,8 +278,11 @@ struct StandaloneHost : Clap::IHost
void activatePlugin(int32_t sr, int32_t minBlock, int32_t maxBlock);
bool isActive{false};

std::vector<RtAudio::Api> getCompiledApi();
std::vector<RtAudio::DeviceInfo> getInputAudioDevices();
std::vector<RtAudio::DeviceInfo> getOutputAudioDevices();
std::vector<int32_t> getSampleRates();
std::vector<uint32_t> getBufferSizes();

clap_input_events inputEvents{};
clap_output_events outputEvents{};
Expand Down
60 changes: 54 additions & 6 deletions src/detail/standalone/standalone_host_audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,19 @@ void StandaloneHost::guaranteeRtAudioDAC()
if (!rtaDac)
{
LOG << "Creating RtAudio DAC" << std::endl;
rtaDac = std::make_unique<RtAudio>(RtAudio::UNSPECIFIED, &rtaErrorCallback);
rtaDac->showWarnings(true);
setAudioApi(RtAudio::Api::UNSPECIFIED);
}
}

void StandaloneHost::setAudioApi(RtAudio::Api api)
{
rtaDac = std::make_unique<RtAudio>(api, &rtaErrorCallback);
audioApi = api;
audioApiName = rtaDac->getApiName(api);
audioApiDisplayName = rtaDac->getApiDisplayName(api);
rtaDac->showWarnings(true);
}

std::tuple<unsigned int, unsigned int, int32_t> StandaloneHost::getDefaultAudioInOutSampleRate()
{
guaranteeRtAudioDAC();
Expand Down Expand Up @@ -109,6 +117,16 @@ std::vector<RtAudio::DeviceInfo> filterDevicesBy(const std::unique_ptr<RtAudio>
return res;
}

std::vector<RtAudio::Api> StandaloneHost::getCompiledApi()
{
guaranteeRtAudioDAC();

std::vector<RtAudio::Api> compiledApi;
rtaDac->getCompiledApi(compiledApi);

return compiledApi;
}

std::vector<RtAudio::DeviceInfo> StandaloneHost::getInputAudioDevices()
{
guaranteeRtAudioDAC();
Expand All @@ -121,6 +139,31 @@ std::vector<RtAudio::DeviceInfo> StandaloneHost::getOutputAudioDevices()
return filterDevicesBy(rtaDac, [](auto &a) { return a.outputChannels > 0; });
}

std::vector<int32_t> StandaloneHost::getSampleRates()
{
guaranteeRtAudioDAC();

std::vector<int32_t> res;

auto samplesRates{rtaDac->getDeviceInfo(audioInputDeviceID).sampleRates};

for (auto &sampleRate : rtaDac->getDeviceInfo(audioInputDeviceID).sampleRates)
{
res.push_back(sampleRate);
}

return res;
}

std::vector<uint32_t> StandaloneHost::getBufferSizes()
{
guaranteeRtAudioDAC();

std::vector<uint32_t> res{16, 32, 48, 64, 96, 128, 144, 160,
192, 224, 256, 480, 512, 1024, 2048, 4096};
return res;
}

void StandaloneHost::startAudioThreadOn(unsigned int inputDeviceID, uint32_t inputChannels,
bool useInput, unsigned int outputDeviceID,
uint32_t outputChannels, bool useOutput, int32_t reqSampleRate)
Expand Down Expand Up @@ -197,17 +240,22 @@ void StandaloneHost::startAudioThreadOn(unsigned int inputDeviceID, uint32_t inp
* this for now at 256 and return to it shortly.
*/
LOG << "[WARNING] Hardcoding frame size to 256 samples for now" << std::endl;
uint32_t bufferFrames{256};

if (currentBufferSize == 0)
{
currentBufferSize = 256;
}

if (rtaDac->openStream((useOutput) ? &oParams : nullptr, (useInput) ? &iParams : nullptr,
RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &rtaCallback, (void *)this,
RTAUDIO_FLOAT32, sampleRate, &currentBufferSize, &rtaCallback, (void *)this,
&options))
{
LOG << "[ERROR]" << rtaDac->getErrorText() << std::endl;
rtaDac->closeStream();
return;
}

activatePlugin(sampleRate, 1, bufferFrames * 2);
activatePlugin(sampleRate, 1, currentBufferSize * 2);

LOG << "RtAudio Attached Devices" << std::endl;
if (useOutput)
Expand Down Expand Up @@ -268,4 +316,4 @@ void StandaloneHost::stopAudioThread()
}
return;
}
} // namespace freeaudio::clap_wrapper::standalone
} // namespace freeaudio::clap_wrapper::standalone
9 changes: 4 additions & 5 deletions src/detail/standalone/standalone_host_midi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@ namespace freeaudio::clap_wrapper::standalone
{
void StandaloneHost::startMIDIThread()
{
unsigned int numPorts{0};
try
{
LOG << "Initializing Midi" << std::endl;
auto midiIn = std::make_unique<RtMidiIn>();
numPorts = midiIn->getPortCount();
numMidiPorts = midiIn->getPortCount();
}
catch (RtMidiError &error)
{
error.printMessage();
exit(EXIT_FAILURE);
}

LOG << "MIDI: There are " << numPorts << " MIDI input sources available. Binding all.\n";
for (unsigned int i = 0; i < numPorts; i++)
LOG << "MIDI: There are " << numMidiPorts << " MIDI input sources available. Binding all.\n";
for (unsigned int i = 0; i < numMidiPorts; i++)
{
try
{
Expand Down Expand Up @@ -74,4 +73,4 @@ void StandaloneHost::stopMIDIThread()
}
}

} // namespace freeaudio::clap_wrapper::standalone
} // namespace freeaudio::clap_wrapper::standalone
Loading

0 comments on commit cd3cac0

Please sign in to comment.