Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows SA: Audio/MIDI settings #307

Merged
merged 7 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 2 additions & 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 All @@ -75,6 +76,7 @@ std::shared_ptr<Clap::Plugin> mainCreatePlugin(const clap_plugin_entry *ee, cons
if (fs::exists(loadPath / "settings.clapwrapper"))
{
LOG << "Trying to load from clap wrapper settings" << std::endl;
fs::create_directories(loadPath);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creat isn't needed since we already know the directory exists from the if above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I forgot we were loading here.. Removed it.

standaloneHost->tryLoadStandaloneAndPluginSettings(loadPath, "settings.clapwrapper");
}
}
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
Loading