2 #include <Audio/AudioInterface.hpp>
3 #include <Audio/PortAudioInterface.hpp>
4 #include <Audio/Settings/Model.hpp>
5 #include <Audio/Settings/View.hpp>
7 #include <score/command/Dispatchers/SettingsCommandDispatcher.hpp>
8 #include <score/tools/Bind.hpp>
9 #include <score/widgets/SignalUtils.hpp>
12 #include <QFormLayout>
13 #include <QPushButton>
15 #if __has_include(<pa_asio.h>)
18 #if !defined(WIN32_LEAN_AND_MEAN)
19 #define WIN32_LEAN_AND_MEAN
21 #if !defined(NOMINMAX)
29 #if __has_include(<pa_asio.h>)
30 class ASIOFactory final
34 SCORE_CONCRETE(
"6b34c6dd-8201-448f-859c-d014f8d01448")
36 std::vector<PortAudioCard> devices;
38 ASIOFactory() { rescan(); }
40 ~ASIOFactory()
override { }
41 bool available() const noexcept
override {
return true; }
50 PortAudioScope portaudio;
52 devices.push_back(PortAudioCard{{}, {}, QObject::tr(
"No device"), -1, 0, 0, {}});
53 for(
int i = 0; i < Pa_GetHostApiCount(); i++)
55 auto hostapi = Pa_GetHostApiInfo(i);
56 if(hostapi->type == PaHostApiTypeId::paASIO)
58 for(
int card = 0; card < hostapi->deviceCount; card++)
60 auto dev_idx = Pa_HostApiDeviceIndexToDeviceIndex(i, card);
61 auto dev = Pa_GetDeviceInfo(dev_idx);
62 auto raw_name = QString::fromUtf8(Pa_GetDeviceInfo(dev_idx)->name);
64 devices.push_back(PortAudioCard{
65 "ASIO", raw_name, raw_name, dev_idx, dev->maxInputChannels,
66 dev->maxOutputChannels, hostapi->type, dev->defaultSampleRate});
72 QString prettyName()
const override {
return QObject::tr(
"ASIO"); }
73 std::shared_ptr<ossia::audio_engine> make_engine(
76 return std::make_shared<ossia::portaudio_engine>(
77 "ossia score", set.getCardIn().toStdString(), set.getCardOut().toStdString(),
78 set.getDefaultIn(), set.getDefaultOut(), set.getRate(), set.getBufferSize(),
82 void setCard(QComboBox* combo, QString val)
84 auto dev_it = ossia::find_if(
85 devices, [&](
const PortAudioCard& d) {
return d.raw_name == val; });
86 if(dev_it != devices.end())
88 combo->setCurrentIndex(dev_it->out_index);
92 QWidget* make_settings(
96 auto w =
new QWidget{parent};
97 auto lay =
new QFormLayout{w};
99 auto card_list =
new QComboBox{w};
100 auto show_ui =
new QPushButton{tr(
"Show Control Panel"), w};
103 card_list->addItem(devices.front().pretty_name, 0);
104 devices.front().out_index = 0;
107 for(std::size_t i = 1; i < devices.size(); i++)
109 auto& card = devices[i];
110 card_list->addItem(card.pretty_name, (
int)i);
111 card.out_index = card_list->count() - 1;
117 lay->addRow(QObject::tr(
"Device"), card_list);
119 auto update_dev = [=, &m, &m_disp](
const PortAudioCard& dev) {
120 if(dev.raw_name != m.getCardOut())
122 m_disp.submitDeferredCommand<Audio::Settings::SetModelCardIn>(m, dev.raw_name);
123 m_disp.submitDeferredCommand<Audio::Settings::SetModelCardOut>(
125 m_disp.submitDeferredCommand<Audio::Settings::SetModelDefaultIn>(
127 m_disp.submitDeferredCommand<Audio::Settings::SetModelDefaultOut>(
133 card_list, SignalUtils::QComboBox_currentIndexChanged_int(), &v, [=](
int i) {
134 auto& device = devices[card_list->itemData(i).toInt()];
138 if(m.getCardOut().isEmpty())
142 update_dev(devices.front());
147 setCard(card_list, m.getCardOut());
152 lay->addWidget(show_ui);
153 connect(show_ui, &QPushButton::clicked,
this, [=] {
154 auto& dev = devices[card_list->itemData(card_list->currentIndex()).toInt()];
155 PortAudioScope portaudio;
156 PaAsio_ShowControlPanel(dev.dev_idx, GetActiveWindow());
160 addBufferSizeWidget(*w, m, v);
161 addSampleRateWidget(*w, m, v);
163 con(m, &Model::changed, w, [=, &m] { setCard(card_list, m.getCardOut()); });
Definition: score-plugin-audio/Audio/Settings/Model.hpp:22
Definition: score-plugin-audio/Audio/Settings/View.hpp:19
Definition: SettingsCommandDispatcher.hpp:10
Used to access all the application-wide state and structures.
Definition: ApplicationContext.hpp:24