Tuner display
This commit is contained in:
+2
-2
@@ -582,7 +582,7 @@ namespace pipedal
|
||||
{
|
||||
int err;
|
||||
|
||||
alsa_device_name = jackServerSettings.GetAlsaDevice();
|
||||
alsa_device_name = jackServerSettings.GetAlsaInputDevice();
|
||||
|
||||
this->numberOfBuffers = jackServerSettings.GetNumberOfBuffers();
|
||||
this->bufferSize = jackServerSettings.GetBufferSize();
|
||||
@@ -1506,7 +1506,7 @@ namespace pipedal
|
||||
snd_pcm_t *captureHandle = nullptr;
|
||||
snd_pcm_hw_params_t *playbackHwParams = nullptr;
|
||||
snd_pcm_hw_params_t *captureHwParams = nullptr;
|
||||
std::string alsaDeviceName = jackServerSettings.GetAlsaDevice();
|
||||
std::string alsaDeviceName = jackServerSettings.GetAlsaInputDevice();
|
||||
bool result = false;
|
||||
|
||||
try
|
||||
|
||||
@@ -241,6 +241,7 @@ void JackServerSettings::Write()
|
||||
JSON_MAP_BEGIN(JackServerSettings)
|
||||
JSON_MAP_REFERENCE(JackServerSettings, valid)
|
||||
JSON_MAP_REFERENCE(JackServerSettings, rebootRequired)
|
||||
JSON_MAP_REFERENCE(JackServerSettings, isJackAudio)
|
||||
JSON_MAP_REFERENCE(JackServerSettings, alsaDevice)
|
||||
JSON_MAP_REFERENCE(JackServerSettings, sampleRate)
|
||||
JSON_MAP_REFERENCE(JackServerSettings, bufferSize)
|
||||
|
||||
+20
-17
@@ -20,11 +20,15 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include "json.hpp"
|
||||
#include "AudioConfig.hpp"
|
||||
|
||||
namespace pipedal {
|
||||
namespace pipedal
|
||||
{
|
||||
// Jack Daemon configuration.
|
||||
class JackServerSettings {
|
||||
class JackServerSettings
|
||||
{
|
||||
bool valid_ = false;
|
||||
bool isJackAudio_ = JACK_HOST ? true : false;
|
||||
bool rebootRequired_ = false;
|
||||
std::string alsaDevice_;
|
||||
uint64_t sampleRate_ = 0;
|
||||
@@ -33,20 +37,21 @@ namespace pipedal {
|
||||
|
||||
public:
|
||||
JackServerSettings();
|
||||
JackServerSettings(const std::string alsaDevice, uint64_t sampleRate, uint32_t bufferSize, uint32_t numberOfBuffers)
|
||||
: valid_(true),
|
||||
alsaDevice_(alsaDevice),
|
||||
sampleRate_(sampleRate),
|
||||
bufferSize_(bufferSize),
|
||||
numberOfBuffers_(numberOfBuffers)
|
||||
JackServerSettings(
|
||||
const std::string alsaInputDevice,
|
||||
uint64_t sampleRate, uint32_t bufferSize, uint32_t numberOfBuffers)
|
||||
: valid_(true),
|
||||
alsaDevice_(alsaInputDevice),
|
||||
sampleRate_(sampleRate),
|
||||
bufferSize_(bufferSize),
|
||||
numberOfBuffers_(numberOfBuffers)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint64_t GetSampleRate() const { return sampleRate_; }
|
||||
uint32_t GetBufferSize() const { return bufferSize_; }
|
||||
uint32_t GetNumberOfBuffers() const { return numberOfBuffers_; }
|
||||
const std::string&GetAlsaDevice() const { return alsaDevice_; }
|
||||
const std::string &GetAlsaInputDevice() const { return alsaDevice_; }
|
||||
|
||||
void ReadJackConfiguration();
|
||||
|
||||
@@ -56,22 +61,20 @@ namespace pipedal {
|
||||
{
|
||||
this->valid_ = true;
|
||||
this->rebootRequired_ = true;
|
||||
this->sampleRate_ = sampleRate; this->bufferSize_ = bufferSize; this->numberOfBuffers_ = numberOfBuffers;
|
||||
this->sampleRate_ = sampleRate;
|
||||
this->bufferSize_ = bufferSize;
|
||||
this->numberOfBuffers_ = numberOfBuffers;
|
||||
}
|
||||
void Write(); // requires root perms.
|
||||
void SetRebootRequired(bool value)
|
||||
{
|
||||
rebootRequired_ = value;
|
||||
}
|
||||
bool Equals(const JackServerSettings&other)
|
||||
bool Equals(const JackServerSettings &other)
|
||||
{
|
||||
return this->sampleRate_ == other.sampleRate_
|
||||
&& this->bufferSize_ == other.bufferSize_
|
||||
&& this->numberOfBuffers_ == other.numberOfBuffers_;
|
||||
return this->alsaDevice_ == other.alsaDevice_ && this->sampleRate_ == other.sampleRate_ && this->bufferSize_ == other.bufferSize_ && this->numberOfBuffers_ == other.numberOfBuffers_;
|
||||
}
|
||||
|
||||
|
||||
DECLARE_JSON_MAP(JackServerSettings);
|
||||
|
||||
};
|
||||
} // namespace
|
||||
+105
-15
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "CommandLineParser.hpp"
|
||||
#include "ss.hpp"
|
||||
#include "PrettyPrinter.hpp"
|
||||
#include <iostream>
|
||||
#include "PiPedalAlsa.hpp"
|
||||
@@ -40,7 +41,8 @@ constexpr int E_XRUN = 3;
|
||||
|
||||
constexpr uint64_t NO_SIGNAL_VALUE = 0x7000000;
|
||||
|
||||
struct TestResult {
|
||||
struct TestResult
|
||||
{
|
||||
int error = 0;
|
||||
uint64_t latency = 0;
|
||||
float cpuOverhead = 0;
|
||||
@@ -62,6 +64,11 @@ void PrintHelp()
|
||||
<< "List available devices.\n\n";
|
||||
pp << HangingIndent() << " -r --rate\t"
|
||||
<< "Sample rate (default 48000).\n\n";
|
||||
pp << HangingIndent() << " -i --in_channels\t"
|
||||
<< "Input channels. Command-seperated list. e.g.: 0,3. Default: all channels.\n\n";
|
||||
pp << HangingIndent() << " -o --out_channels\t"
|
||||
<< "Output channels. Command-seperated list. e.g.: 0,1,4. Default: all channels.\n\n";
|
||||
|
||||
pp << HangingIndent() << " -h --help\t"
|
||||
<< "Display this message.\n\n";
|
||||
|
||||
@@ -107,6 +114,9 @@ void ListDevices()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using ChannelsT = std::vector<int>;
|
||||
|
||||
class AlsaTester : private AudioDriverHost
|
||||
{
|
||||
public:
|
||||
@@ -121,14 +131,22 @@ private:
|
||||
AudioDriver *audioDriver = nullptr;
|
||||
|
||||
const std::string &deviceId;
|
||||
ChannelsT inputChannels;
|
||||
ChannelsT outputChannels;
|
||||
uint32_t sampleRate;
|
||||
int bufferSize;
|
||||
int buffers;
|
||||
|
||||
public:
|
||||
AlsaTester(const std::string &deviceId, uint32_t sampleRate, int bufferSize, int buffers)
|
||||
AlsaTester(
|
||||
const std::string &deviceId,
|
||||
const ChannelsT &inputChannels,
|
||||
const ChannelsT &outputChannels,
|
||||
uint32_t sampleRate, int bufferSize, int buffers)
|
||||
: deviceId(deviceId),
|
||||
sampleRate(sampleRate),
|
||||
inputChannels(inputChannels),
|
||||
outputChannels(outputChannels),
|
||||
bufferSize(bufferSize),
|
||||
buffers(buffers)
|
||||
{
|
||||
@@ -139,6 +157,21 @@ public:
|
||||
delete[] inputBuffers;
|
||||
delete[] outputBuffers;
|
||||
}
|
||||
std::vector<std::string> SelectChannels(const std::vector<std::string>&available, const std::vector<int>& selection)
|
||||
{
|
||||
if (selection.size() == 0) return available;
|
||||
|
||||
std::vector<std::string> result;
|
||||
for (int sel: selection)
|
||||
{
|
||||
if (sel < 0 || sel >= available.size())
|
||||
{
|
||||
throw PiPedalArgumentException(SS("Invalid channel: " + sel));
|
||||
}
|
||||
result.push_back(available[sel]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
TestResult Test()
|
||||
{
|
||||
@@ -150,9 +183,17 @@ public:
|
||||
JackConfiguration jackConfiguration;
|
||||
jackConfiguration.AlsaInitialize(serverSettings);
|
||||
|
||||
auto & availableInputs = jackConfiguration.GetInputAudioPorts();
|
||||
auto & availableOutputs = jackConfiguration.GetOutputAudioPorts();
|
||||
|
||||
|
||||
std::vector<std::string> inputAudioPorts, outputAudioPorts;
|
||||
|
||||
inputAudioPorts = SelectChannels(availableInputs,this->inputChannels);
|
||||
outputAudioPorts = SelectChannels(availableOutputs,this->outputChannels);
|
||||
|
||||
JackChannelSelection channelSelection(
|
||||
jackConfiguration.GetInputAudioPorts(),
|
||||
jackConfiguration.GetOutputAudioPorts(),
|
||||
inputAudioPorts, outputAudioPorts,
|
||||
std::vector<AlsaMidiDeviceInfo>());
|
||||
|
||||
audioDriver = CreateAlsaDriver(this);
|
||||
@@ -176,11 +217,11 @@ public:
|
||||
|
||||
if (this->GetXruns() != 0)
|
||||
{
|
||||
result.error = E_XRUN;
|
||||
result.error = E_XRUN;
|
||||
return result;
|
||||
}
|
||||
result.latency = latencyMonitor.GetLatency();
|
||||
if (result.latency == NO_SIGNAL_VALUE)
|
||||
result.latency = latencyMonitor.GetLatency();
|
||||
if (result.latency == NO_SIGNAL_VALUE)
|
||||
{
|
||||
result.error = E_NOSIGNAL;
|
||||
}
|
||||
@@ -267,7 +308,7 @@ public:
|
||||
state = State::Waiting;
|
||||
current_latency = 0;
|
||||
}
|
||||
return 0.01;
|
||||
return 0.001;
|
||||
}
|
||||
break;
|
||||
case State::Waiting:
|
||||
@@ -349,9 +390,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
TestResult RunLatencyTest(const std::string deviceId, uint32_t sampleRate, int bufferSize, int buffers)
|
||||
TestResult RunLatencyTest(
|
||||
const std::string deviceId,
|
||||
const ChannelsT &inputChannels,
|
||||
const ChannelsT &outputChannels,
|
||||
uint32_t sampleRate, int bufferSize, int buffers)
|
||||
{
|
||||
AlsaTester tester(deviceId, sampleRate, bufferSize, buffers);
|
||||
AlsaTester tester(deviceId, inputChannels, outputChannels, sampleRate, bufferSize, buffers);
|
||||
return tester.Test();
|
||||
}
|
||||
|
||||
@@ -360,7 +405,7 @@ static std::string msDisplay(float value)
|
||||
std::stringstream s;
|
||||
s << fixed;
|
||||
s.precision(1);
|
||||
s << value << "ms";
|
||||
s << value << "ms";
|
||||
return s.str();
|
||||
}
|
||||
static std::string overheadDisplay(float value)
|
||||
@@ -370,7 +415,11 @@ static std::string overheadDisplay(float value)
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void RunLatencyTest(const std::string &deviceId, uint32_t sampleRate)
|
||||
void RunLatencyTest(
|
||||
const std::string &deviceId,
|
||||
const ChannelsT &inputChannels,
|
||||
const ChannelsT &outputChannels,
|
||||
uint32_t sampleRate)
|
||||
{
|
||||
PrettyPrinter pp;
|
||||
pp << "Device: " << deviceId << " Rate: " << sampleRate << "\n\n";
|
||||
@@ -400,7 +449,7 @@ void RunLatencyTest(const std::string &deviceId, uint32_t sampleRate)
|
||||
|
||||
for (auto bufferCount : bufferCounts)
|
||||
{
|
||||
auto result = RunLatencyTest(deviceId, sampleRate, bufferSize, bufferCount);
|
||||
auto result = RunLatencyTest(deviceId, inputChannels,outputChannels, sampleRate, bufferSize, bufferCount);
|
||||
|
||||
pp.Column(column);
|
||||
column += BUFFERS_COLUMN_WIDTH;
|
||||
@@ -419,7 +468,7 @@ void RunLatencyTest(const std::string &deviceId, uint32_t sampleRate)
|
||||
default:
|
||||
{
|
||||
float ms = 1000.0f * result.latency / sampleRate;
|
||||
pp << result.latency << "/" << msDisplay(ms) ;
|
||||
pp << result.latency << "/" << msDisplay(ms);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -428,6 +477,39 @@ void RunLatencyTest(const std::string &deviceId, uint32_t sampleRate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ChannelsT ParseChannels(const std::string&channels)
|
||||
{
|
||||
ChannelsT result;
|
||||
std::stringstream s(channels);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int c = s.peek();
|
||||
if (c == -1) break;
|
||||
|
||||
if (c == ',') {
|
||||
s.get();
|
||||
c = s.peek();
|
||||
}
|
||||
if (c < '0' || c > '9')
|
||||
{
|
||||
throw PiPedalArgumentException("Invalid channel selection: " + channels);
|
||||
}
|
||||
int v = 0;
|
||||
while (s.peek() >= '0' && s.peek() <= '9')
|
||||
{
|
||||
c = s.get();
|
||||
v = v*10 + c-'0';
|
||||
}
|
||||
result.push_back(v);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
|
||||
@@ -439,10 +521,16 @@ int main(int argc, const char **argv)
|
||||
bool listDevices = false;
|
||||
bool help = false;
|
||||
uint32_t sampleRate = 48000;
|
||||
std:
|
||||
string strInputChannels, strOutputChannels;
|
||||
|
||||
ChannelsT inputChannels, outputChannels;
|
||||
|
||||
parser.AddOption("l", "list", &listDevices);
|
||||
parser.AddOption("h", "help", &help);
|
||||
parser.AddOption("r", "rate", &sampleRate);
|
||||
parser.AddOption("i", "in_channels", &strInputChannels);
|
||||
parser.AddOption("o", "out_channels", &strOutputChannels);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -458,7 +546,9 @@ int main(int argc, const char **argv)
|
||||
}
|
||||
else if (parser.Arguments().size() == 1)
|
||||
{
|
||||
RunLatencyTest(parser.Arguments()[0], sampleRate);
|
||||
inputChannels = ParseChannels(strInputChannels);
|
||||
outputChannels = ParseChannels(strInputChannels);
|
||||
RunLatencyTest(parser.Arguments()[0], inputChannels, outputChannels, sampleRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+252
-218
@@ -24,6 +24,7 @@
|
||||
#include "viewstream.hpp"
|
||||
#include "PiPedalVersion.hpp"
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include "Lv2Log.hpp"
|
||||
#include "JackConfiguration.hpp"
|
||||
#include <future>
|
||||
@@ -41,14 +42,13 @@
|
||||
using namespace std;
|
||||
using namespace pipedal;
|
||||
|
||||
|
||||
class NotifyMidiListenerBody {
|
||||
class NotifyMidiListenerBody
|
||||
{
|
||||
public:
|
||||
int64_t clientHandle_;
|
||||
bool isNote_;
|
||||
int32_t noteOrControl_;
|
||||
DECLARE_JSON_MAP(NotifyMidiListenerBody);
|
||||
|
||||
};
|
||||
JSON_MAP_BEGIN(NotifyMidiListenerBody)
|
||||
JSON_MAP_REFERENCE(NotifyMidiListenerBody, clientHandle)
|
||||
@@ -56,7 +56,8 @@ JSON_MAP_REFERENCE(NotifyMidiListenerBody, isNote)
|
||||
JSON_MAP_REFERENCE(NotifyMidiListenerBody, noteOrControl)
|
||||
JSON_MAP_END()
|
||||
|
||||
class NotifyAtomOutputBody {
|
||||
class NotifyAtomOutputBody
|
||||
{
|
||||
public:
|
||||
int64_t clientHandle_;
|
||||
uint64_t instanceId_;
|
||||
@@ -71,8 +72,9 @@ JSON_MAP_REFERENCE(NotifyAtomOutputBody, instanceId)
|
||||
JSON_MAP_REFERENCE(NotifyAtomOutputBody, atomJson)
|
||||
JSON_MAP_END()
|
||||
|
||||
class ListenForMidiEventBody {
|
||||
public:
|
||||
class ListenForMidiEventBody
|
||||
{
|
||||
public:
|
||||
bool listenForControlsOnly_;
|
||||
int64_t handle_;
|
||||
DECLARE_JSON_MAP(ListenForMidiEventBody);
|
||||
@@ -83,8 +85,9 @@ JSON_MAP_REFERENCE(ListenForMidiEventBody, listenForControlsOnly)
|
||||
JSON_MAP_REFERENCE(ListenForMidiEventBody, handle)
|
||||
JSON_MAP_END()
|
||||
|
||||
class ListenForAtomOutputBody {
|
||||
public:
|
||||
class ListenForAtomOutputBody
|
||||
{
|
||||
public:
|
||||
uint64_t instanceId_;
|
||||
int64_t handle_;
|
||||
DECLARE_JSON_MAP(ListenForAtomOutputBody);
|
||||
@@ -95,9 +98,9 @@ JSON_MAP_REFERENCE(ListenForAtomOutputBody, instanceId)
|
||||
JSON_MAP_REFERENCE(ListenForAtomOutputBody, handle)
|
||||
JSON_MAP_END()
|
||||
|
||||
|
||||
class OnLoadPluginPresetBody {
|
||||
public:
|
||||
class OnLoadPluginPresetBody
|
||||
{
|
||||
public:
|
||||
int64_t instanceId_;
|
||||
std::vector<ControlValue> controlValues_;
|
||||
DECLARE_JSON_MAP(OnLoadPluginPresetBody);
|
||||
@@ -108,8 +111,9 @@ JSON_MAP_REFERENCE(OnLoadPluginPresetBody, instanceId)
|
||||
JSON_MAP_REFERENCE(OnLoadPluginPresetBody, controlValues)
|
||||
JSON_MAP_END()
|
||||
|
||||
class LoadPluginPresetBody {
|
||||
public:
|
||||
class LoadPluginPresetBody
|
||||
{
|
||||
public:
|
||||
uint64_t pluginInstanceId_;
|
||||
uint64_t presetInstanceId_;
|
||||
DECLARE_JSON_MAP(LoadPluginPresetBody);
|
||||
@@ -147,7 +151,6 @@ JSON_MAP_REFERENCE(MonitorResultBody, subscriptionHandle)
|
||||
JSON_MAP_REFERENCE(MonitorResultBody, value)
|
||||
JSON_MAP_END()
|
||||
|
||||
|
||||
class GetLv2ParameterBody
|
||||
{
|
||||
public:
|
||||
@@ -204,15 +207,15 @@ JSON_MAP_REFERENCE(SavePluginPresetAsBody, instanceId)
|
||||
JSON_MAP_REFERENCE(SavePluginPresetAsBody, name)
|
||||
JSON_MAP_END()
|
||||
|
||||
class RenameBankBody {
|
||||
class RenameBankBody
|
||||
{
|
||||
public:
|
||||
int64_t bankId_;
|
||||
std::string newName_;
|
||||
DECLARE_JSON_MAP(RenameBankBody);
|
||||
|
||||
};
|
||||
JSON_MAP_BEGIN(RenameBankBody)
|
||||
JSON_MAP_REFERENCE(RenameBankBody,bankId)
|
||||
JSON_MAP_REFERENCE(RenameBankBody, bankId)
|
||||
JSON_MAP_REFERENCE(RenameBankBody, newName)
|
||||
JSON_MAP_END()
|
||||
|
||||
@@ -332,15 +335,11 @@ JSON_MAP_REFERENCE(ControlChangedBody, symbol)
|
||||
JSON_MAP_REFERENCE(ControlChangedBody, value)
|
||||
JSON_MAP_END()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class PiPedalSocketHandler : public SocketHandler, public IPiPedalModelSubscriber
|
||||
{
|
||||
private:
|
||||
AdminClient& GetAdminClient() const {
|
||||
AdminClient &GetAdminClient() const
|
||||
{
|
||||
return model.GetAdminClient();
|
||||
}
|
||||
void RequestShutdown(bool restart);
|
||||
@@ -364,8 +363,11 @@ private:
|
||||
{
|
||||
int64_t subscriptionHandle = -1;
|
||||
int64_t instanceId = -1;
|
||||
bool waitingForAck = false;
|
||||
std::string key;
|
||||
|
||||
float lastSentValue = 0;
|
||||
bool pendingValue = false;
|
||||
bool waitingForAck = false;
|
||||
};
|
||||
|
||||
std::vector<PortMonitorSubscription> activePortMonitors;
|
||||
@@ -396,9 +398,9 @@ public:
|
||||
: model(model), clientId(++nextClientId)
|
||||
{
|
||||
std::stringstream imageList;
|
||||
const std::filesystem::path& webRoot = model.GetWebRoot() / "img";
|
||||
const std::filesystem::path &webRoot = model.GetWebRoot() / "img";
|
||||
bool firstTime = true;
|
||||
for (const auto&entry: std::filesystem::directory_iterator(webRoot))
|
||||
for (const auto &entry : std::filesystem::directory_iterator(webRoot))
|
||||
{
|
||||
if (!firstTime)
|
||||
{
|
||||
@@ -407,7 +409,7 @@ public:
|
||||
firstTime = false;
|
||||
imageList << entry.path().filename().string();
|
||||
}
|
||||
this->imageList = imageList.str();
|
||||
this->imageList = imageList.str();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -637,40 +639,89 @@ public:
|
||||
Reply(replyTo, "error", what);
|
||||
}
|
||||
|
||||
bool waitingForPortMonitorAck(uint64_t subscriptionId)
|
||||
PortMonitorSubscription *getPortMonitorSubscription(uint64_t subscriptionId)
|
||||
{
|
||||
for (int i = 0; i < this->activePortMonitors.size(); ++i)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(subscriptionMutex);
|
||||
for (int i = 0; i < this->activePortMonitors.size(); ++i)
|
||||
auto *portMonitor = &activePortMonitors[i];
|
||||
if (portMonitor->subscriptionHandle == subscriptionId)
|
||||
{
|
||||
auto &portMonitor = activePortMonitors[i];
|
||||
if (portMonitor.subscriptionHandle == subscriptionId)
|
||||
{
|
||||
if (portMonitor.waitingForAck)
|
||||
return true;
|
||||
portMonitor.waitingForAck = true;
|
||||
return false;
|
||||
}
|
||||
return portMonitor;
|
||||
}
|
||||
}
|
||||
return true; // subscription has been closed. don't sent to client.
|
||||
return nullptr;
|
||||
}
|
||||
void portMonitorAck(uint64_t subscriptionId)
|
||||
|
||||
void SendMonitorPortMessage(PortMonitorSubscription *subscription, float value)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(subscriptionMutex);
|
||||
for (int i = 0; i < this->activePortMonitors.size(); ++i)
|
||||
|
||||
auto subscriptionHandle_ = subscription->subscriptionHandle;
|
||||
MonitorResultBody body;
|
||||
body.subscriptionHandle_ = subscriptionHandle_;
|
||||
body.value_ = value;
|
||||
this->Request<bool, MonitorResultBody>( // send the message and wait for a response.
|
||||
"onMonitorPortOutput",
|
||||
body,
|
||||
[this, subscriptionHandle_](const bool &result)
|
||||
{
|
||||
auto &portMonitor = activePortMonitors[i];
|
||||
if (portMonitor.subscriptionHandle == subscriptionId)
|
||||
PortMonitorSubscription *subscription = getPortMonitorSubscription(subscriptionHandle_);
|
||||
if (subscription == nullptr) return;
|
||||
|
||||
if (subscription->pendingValue)
|
||||
{
|
||||
portMonitor.waitingForAck = false;
|
||||
break;
|
||||
subscription->pendingValue = false;
|
||||
SendMonitorPortMessage(subscription, subscription->lastSentValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
subscription->waitingForAck = false;
|
||||
}
|
||||
},
|
||||
[](const std::exception &e)
|
||||
{
|
||||
Lv2Log::debug("Failed to monitor port output. (%s)", e.what());
|
||||
});
|
||||
}
|
||||
void MonitorPort(int replyTo,MonitorPortBody &body)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(subscriptionMutex);
|
||||
int64_t subscriptionHandle = model.MonitorPort(
|
||||
body.instanceId_,
|
||||
body.key_,
|
||||
body.updateRate_,
|
||||
[this](int64_t subscriptionHandle_, float value)
|
||||
{
|
||||
PortMonitorSubscription *subscription = getPortMonitorSubscription(subscriptionHandle_);
|
||||
|
||||
if (subscription)
|
||||
{
|
||||
if (subscription->waitingForAck)
|
||||
{
|
||||
if (subscription->lastSentValue != value)
|
||||
{
|
||||
subscription->lastSentValue = value;
|
||||
subscription->pendingValue = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subscription->lastSentValue = value;
|
||||
|
||||
subscription->waitingForAck = true;
|
||||
SendMonitorPortMessage(subscription, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
activePortMonitors.push_back(
|
||||
PortMonitorSubscription{subscriptionHandle, body.instanceId_, body.key_});
|
||||
|
||||
this->Reply(replyTo, "monitorPort", subscriptionHandle);
|
||||
}
|
||||
|
||||
/***********************/
|
||||
|
||||
void handleMessage(int reply, int replyTo, const std::string &message, json_reader *pReader)
|
||||
{
|
||||
if (reply != -1)
|
||||
@@ -723,66 +774,66 @@ public:
|
||||
{
|
||||
ListenForMidiEventBody body;
|
||||
pReader->read(&body);
|
||||
this->model.ListenForMidiEvent(this->clientId,body.handle_, body.listenForControlsOnly_);
|
||||
this->model.ListenForMidiEvent(this->clientId, body.handle_, body.listenForControlsOnly_);
|
||||
}
|
||||
else if (message == "cancelListenForMidiEvent")
|
||||
{
|
||||
uint64_t handle;
|
||||
pReader->read(&handle);
|
||||
this->model.CancelListenForMidiEvent(this->clientId,handle);
|
||||
this->model.CancelListenForMidiEvent(this->clientId, handle);
|
||||
}
|
||||
else if (message == "listenForAtomOutput")
|
||||
{
|
||||
ListenForAtomOutputBody body;
|
||||
pReader->read(&body);
|
||||
this->model.ListenForAtomOutputs(this->clientId,body.handle_, body.instanceId_);
|
||||
this->model.ListenForAtomOutputs(this->clientId, body.handle_, body.instanceId_);
|
||||
}
|
||||
else if (message == "cancelListenForAtomOutput")
|
||||
{
|
||||
int64_t handle;
|
||||
pReader->read(&handle);
|
||||
this->model.CancelListenForMidiEvent(this->clientId,handle);
|
||||
this->model.CancelListenForMidiEvent(this->clientId, handle);
|
||||
}
|
||||
|
||||
else if (message == "getJackStatus")
|
||||
{
|
||||
JackHostStatus status = model.GetJackStatus();
|
||||
this->Reply(replyTo,"getJackStatus",status);
|
||||
} else if (message == "getAlsaDevices")
|
||||
this->Reply(replyTo, "getJackStatus", status);
|
||||
}
|
||||
else if (message == "getAlsaDevices")
|
||||
{
|
||||
std::vector<AlsaDeviceInfo> devices = model.GetAlsaDevices();
|
||||
this->Reply(replyTo,"getAlsaDevices",devices);
|
||||
|
||||
|
||||
} else if (message == "getWifiChannels")
|
||||
this->Reply(replyTo, "getAlsaDevices", devices);
|
||||
}
|
||||
else if (message == "getWifiChannels")
|
||||
{
|
||||
std::string country;
|
||||
pReader->read(&country);
|
||||
std::vector<WifiChannel> channels = pipedal::getWifiChannels(country.c_str());
|
||||
this->Reply(replyTo,"getWifiChannels",channels);
|
||||
this->Reply(replyTo, "getWifiChannels", channels);
|
||||
}
|
||||
else if (message == "getPluginPresets")
|
||||
{
|
||||
std::string uri;
|
||||
pReader->read(&uri);
|
||||
this->Reply(replyTo,"getPluginPresets",this->model.GetPluginUiPresets(uri));
|
||||
this->Reply(replyTo, "getPluginPresets", this->model.GetPluginUiPresets(uri));
|
||||
}
|
||||
else if (message == "loadPluginPreset")
|
||||
{
|
||||
LoadPluginPresetBody body;
|
||||
pReader->read(&body);
|
||||
this->model.LoadPluginPreset(body.pluginInstanceId_,body.presetInstanceId_);
|
||||
|
||||
this->model.LoadPluginPreset(body.pluginInstanceId_, body.presetInstanceId_);
|
||||
}
|
||||
else if (message == "setJackServerSettings") {
|
||||
else if (message == "setJackServerSettings")
|
||||
{
|
||||
JackServerSettings jackServerSettings;
|
||||
pReader->read(&jackServerSettings);
|
||||
this->model.SetJackServerSettings(jackServerSettings);
|
||||
this->Reply(replyTo,"setJackserverSettings");
|
||||
|
||||
this->Reply(replyTo, "setJackserverSettings");
|
||||
}
|
||||
else if (message == "setGovernorSettings") {
|
||||
std::string governor;
|
||||
else if (message == "setGovernorSettings")
|
||||
{
|
||||
std::string governor;
|
||||
pReader->read(&governor);
|
||||
std::string fromAddress = this->getFromAddress();
|
||||
if (!IsOnLocalSubnet(fromAddress))
|
||||
@@ -790,9 +841,10 @@ public:
|
||||
throw PiPedalException("Permission denied. Not on local subnet.");
|
||||
}
|
||||
this->model.SetGovernorSettings(governor);
|
||||
this->Reply(replyTo,"setGovernorSettings");
|
||||
this->Reply(replyTo, "setGovernorSettings");
|
||||
}
|
||||
else if (message == "setWifiConfigSettings") {
|
||||
else if (message == "setWifiConfigSettings")
|
||||
{
|
||||
WifiConfigSettings wifiConfigSettings;
|
||||
pReader->read(&wifiConfigSettings);
|
||||
if (!GetAdminClient().CanUseShutdownClient())
|
||||
@@ -805,15 +857,15 @@ public:
|
||||
throw PiPedalException("Permission denied. Not on local subnet.");
|
||||
}
|
||||
|
||||
|
||||
this->model.SetWifiConfigSettings(wifiConfigSettings);
|
||||
this->Reply(replyTo,"setWifiConfigSettings");
|
||||
this->Reply(replyTo, "setWifiConfigSettings");
|
||||
}
|
||||
else if (message == "getWifiConfigSettings") {
|
||||
else if (message == "getWifiConfigSettings")
|
||||
{
|
||||
this->Reply(replyTo, "getWifiConfigSettings", model.GetWifiConfigSettings());
|
||||
|
||||
}
|
||||
else if (message == "setWifiDirectConfigSettings") {
|
||||
else if (message == "setWifiDirectConfigSettings")
|
||||
{
|
||||
WifiDirectConfigSettings wifiDirectConfigSettings;
|
||||
pReader->read(&wifiDirectConfigSettings);
|
||||
if (!GetAdminClient().CanUseShutdownClient())
|
||||
@@ -826,28 +878,27 @@ public:
|
||||
throw PiPedalException("Permission denied. Not on local subnet.");
|
||||
}
|
||||
|
||||
|
||||
this->model.SetWifiDirectConfigSettings(wifiDirectConfigSettings);
|
||||
this->Reply(replyTo,"setWifiDirectConfigSettings");
|
||||
this->Reply(replyTo, "setWifiDirectConfigSettings");
|
||||
}
|
||||
else if (message == "getWifiDirectConfigSettings") {
|
||||
else if (message == "getWifiDirectConfigSettings")
|
||||
{
|
||||
this->Reply(replyTo, "getWifiDirectConfigSettings", model.GetWifiDirectConfigSettings());
|
||||
|
||||
}
|
||||
|
||||
else if (message == "getGovernorSettings") {
|
||||
else if (message == "getGovernorSettings")
|
||||
{
|
||||
this->Reply(replyTo, "getGovernorSettings", model.GetGovernorSettings());
|
||||
|
||||
}
|
||||
|
||||
else if (message == "getJackServerSettings") {
|
||||
else if (message == "getJackServerSettings")
|
||||
{
|
||||
this->Reply(replyTo, "getJackServerSettings", model.GetJackServerSettings());
|
||||
|
||||
}
|
||||
else if (message == "getBankIndex") {
|
||||
else if (message == "getBankIndex")
|
||||
{
|
||||
BankIndex bankIndex = model.GetBankIndex();
|
||||
this->Reply(replyTo, "getBankIndex", bankIndex);
|
||||
|
||||
}
|
||||
else if (message == "getJackConfiguration")
|
||||
{
|
||||
@@ -932,7 +983,7 @@ public:
|
||||
}
|
||||
else if (message == "getShowStatusMonitor")
|
||||
{
|
||||
Reply(replyTo,"getShowStatusMonitor",this->model.GetShowStatusMonitor());
|
||||
Reply(replyTo, "getShowStatusMonitor", this->model.GetShowStatusMonitor());
|
||||
}
|
||||
else if (message == "version")
|
||||
{
|
||||
@@ -970,15 +1021,15 @@ public:
|
||||
else if (message == "shutdown")
|
||||
{
|
||||
PresetIndex newIndex;
|
||||
|
||||
|
||||
RequestShutdown(false);
|
||||
this->Reply(replyTo,"shutdown");
|
||||
this->Reply(replyTo, "shutdown");
|
||||
}
|
||||
else if (message == "restart")
|
||||
{
|
||||
PresetIndex newIndex;
|
||||
RequestShutdown(true);
|
||||
this->Reply(replyTo,"restart");
|
||||
this->Reply(replyTo, "restart");
|
||||
}
|
||||
else if (message == "deletePresetItem")
|
||||
{
|
||||
@@ -1007,40 +1058,46 @@ public:
|
||||
json_reader tReader(tIn);
|
||||
std::string tResult;
|
||||
tReader.read(&tResult);
|
||||
|
||||
|
||||
body.newName_ = tResult;
|
||||
|
||||
|
||||
try {
|
||||
model.RenameBank(this->clientId,body.bankId_, body.newName_);
|
||||
this->Reply(replyTo, "renameBank");
|
||||
} catch (const std::exception &e)
|
||||
try
|
||||
{
|
||||
this->SendError(replyTo,std::string(e.what()));
|
||||
model.RenameBank(this->clientId, body.bankId_, body.newName_);
|
||||
this->Reply(replyTo, "renameBank");
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
this->SendError(replyTo, std::string(e.what()));
|
||||
}
|
||||
}
|
||||
else if (message == "openBank")
|
||||
{
|
||||
int64_t bankId = -1;
|
||||
pReader->read(&bankId);
|
||||
try {
|
||||
model.OpenBank(this->clientId,bankId);;
|
||||
this->Reply(replyTo, "openBank");
|
||||
} catch (const std::exception &e)
|
||||
try
|
||||
{
|
||||
this->SendError(replyTo,std::string(e.what()));
|
||||
model.OpenBank(this->clientId, bankId);
|
||||
;
|
||||
this->Reply(replyTo, "openBank");
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
this->SendError(replyTo, std::string(e.what()));
|
||||
}
|
||||
}
|
||||
else if (message == "saveBankAs")
|
||||
{
|
||||
RenameBankBody body;
|
||||
pReader->read(&body);
|
||||
try {
|
||||
int64_t newId = model.SaveBankAs(this->clientId,body.bankId_, body.newName_);
|
||||
this->Reply(replyTo, "saveBankAs",newId);
|
||||
} catch (const std::exception &e)
|
||||
try
|
||||
{
|
||||
this->SendError(replyTo,std::string(e.what()));
|
||||
int64_t newId = model.SaveBankAs(this->clientId, body.bankId_, body.newName_);
|
||||
this->Reply(replyTo, "saveBankAs", newId);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
this->SendError(replyTo, std::string(e.what()));
|
||||
}
|
||||
}
|
||||
else if (message == "renamePresetItem")
|
||||
@@ -1057,31 +1114,31 @@ public:
|
||||
pReader->read(&body);
|
||||
int64_t result = model.CopyPreset(body.clientId_, body.fromId_, body.toId_);
|
||||
this->Reply(replyTo, "copyPreset", result);
|
||||
}
|
||||
}
|
||||
else if (message == "copyPluginPreset")
|
||||
{
|
||||
CopyPluginPresetBody body;
|
||||
pReader->read(&body);
|
||||
uint64_t result = model.CopyPluginPreset(body.pluginUri_,body.instanceId_);
|
||||
uint64_t result = model.CopyPluginPreset(body.pluginUri_, body.instanceId_);
|
||||
this->Reply(replyTo, "copyPluginPreset", result);
|
||||
}
|
||||
else if (message =="getLv2Parameter")
|
||||
}
|
||||
else if (message == "getLv2Parameter")
|
||||
{
|
||||
GetLv2ParameterBody body;
|
||||
pReader->read(&body);
|
||||
|
||||
|
||||
model.GetLv2Parameter(
|
||||
this->clientId,
|
||||
body.instanceId_,
|
||||
body.uri_,
|
||||
[this,replyTo] (const std::string &jsonResult)
|
||||
[this, replyTo](const std::string &jsonResult)
|
||||
{
|
||||
this->JsonReply(replyTo,"getLv2Parameter",jsonResult.c_str());
|
||||
this->JsonReply(replyTo, "getLv2Parameter", jsonResult.c_str());
|
||||
},
|
||||
[this,replyTo] (const std::string &error) {
|
||||
this->SendError(replyTo,error.c_str());
|
||||
[this, replyTo](const std::string &error)
|
||||
{
|
||||
this->SendError(replyTo, error.c_str());
|
||||
});
|
||||
|
||||
}
|
||||
else if (message == "monitorPort")
|
||||
{
|
||||
@@ -1089,38 +1146,7 @@ public:
|
||||
MonitorPortBody body;
|
||||
pReader->read(&body);
|
||||
|
||||
int64_t subscriptionHandle = model.MonitorPort(
|
||||
body.instanceId_,
|
||||
body.key_,
|
||||
body.updateRate_,
|
||||
[this](int64_t subscriptionHandle_, float value)
|
||||
{
|
||||
MonitorResultBody body;
|
||||
body.subscriptionHandle_ = subscriptionHandle_;
|
||||
body.value_ = value;
|
||||
if (!waitingForPortMonitorAck(subscriptionHandle_)) //only one outstanding response.
|
||||
{
|
||||
this->Request<bool, MonitorResultBody>( // send the message and wait for a response.
|
||||
"onMonitorPortOutput",
|
||||
body,
|
||||
[this, subscriptionHandle_](const bool &result)
|
||||
{
|
||||
this->portMonitorAck(subscriptionHandle_); // please can we have some more.
|
||||
|
||||
},
|
||||
[](const std::exception &e)
|
||||
{
|
||||
Lv2Log::debug("Failed to monitor port output. (%s)", e.what());
|
||||
});
|
||||
}
|
||||
});
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(subscriptionMutex);
|
||||
activePortMonitors.push_back(
|
||||
PortMonitorSubscription{subscriptionHandle, body.instanceId_,false, body.key_});
|
||||
}
|
||||
|
||||
this->Reply(replyTo, "monitorPort", subscriptionHandle);
|
||||
MonitorPort(replyTo,body);
|
||||
}
|
||||
else if (message == "unmonitorPort")
|
||||
{
|
||||
@@ -1175,16 +1201,17 @@ public:
|
||||
}
|
||||
else if (message == "imageList")
|
||||
{
|
||||
|
||||
this->Reply(replyTo, "imageList", imageList);
|
||||
} else if (message == "getFavorites")
|
||||
{
|
||||
std::map<std::string,bool> favorites = this->model.GetFavorites();
|
||||
this->Reply(replyTo,"getFavorites",favorites);
|
||||
|
||||
} else if (message == "setFavorites")
|
||||
this->Reply(replyTo, "imageList", imageList);
|
||||
}
|
||||
else if (message == "getFavorites")
|
||||
{
|
||||
std::map<std::string,bool> favorites;
|
||||
std::map<std::string, bool> favorites = this->model.GetFavorites();
|
||||
this->Reply(replyTo, "getFavorites", favorites);
|
||||
}
|
||||
else if (message == "setFavorites")
|
||||
{
|
||||
std::map<std::string, bool> favorites;
|
||||
pReader->read(&favorites);
|
||||
this->model.SetFavorites(favorites);
|
||||
}
|
||||
@@ -1254,20 +1281,21 @@ protected:
|
||||
{
|
||||
SendError(replyTo, e.what());
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
SendError(replyTo, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void OnFavoritesChanged(const std::map<std::string,bool> &favorites)
|
||||
virtual void OnFavoritesChanged(const std::map<std::string, bool> &favorites)
|
||||
{
|
||||
Send("onFavoritesChanged",favorites);
|
||||
Send("onFavoritesChanged", favorites);
|
||||
}
|
||||
|
||||
virtual void OnShowStatusMonitorChanged(bool show) {
|
||||
Send("onShowStatusMonitorChanged",show);
|
||||
virtual void OnShowStatusMonitorChanged(bool show)
|
||||
{
|
||||
Send("onShowStatusMonitorChanged", show);
|
||||
}
|
||||
|
||||
virtual void OnChannelSelectionChanged(int64_t clientId, const JackChannelSelection &channelSelection)
|
||||
@@ -1284,7 +1312,7 @@ public:
|
||||
body.presets_ = const_cast<PresetIndex *>(&presets);
|
||||
Send("onPresetsChanged", body);
|
||||
}
|
||||
virtual void OnPluginPresetsChanged(const std::string&pluginUri)
|
||||
virtual void OnPluginPresetsChanged(const std::string &pluginUri)
|
||||
{
|
||||
Send("onPluginPresetsChanged", pluginUri);
|
||||
}
|
||||
@@ -1293,14 +1321,14 @@ public:
|
||||
Send("onJackConfigurationChanged", jackConfiguration);
|
||||
}
|
||||
|
||||
virtual void OnLoadPluginPreset(int64_t instanceId,const std::vector<ControlValue>&controlValues) {
|
||||
virtual void OnLoadPluginPreset(int64_t instanceId, const std::vector<ControlValue> &controlValues)
|
||||
{
|
||||
OnLoadPluginPresetBody body;
|
||||
body.instanceId_ = instanceId;
|
||||
body.controlValues_ = const_cast<std::vector<ControlValue>&>(controlValues);
|
||||
Send("onLoadPluginPreset",body);
|
||||
body.controlValues_ = const_cast<std::vector<ControlValue> &>(controlValues);
|
||||
Send("onLoadPluginPreset", body);
|
||||
}
|
||||
|
||||
|
||||
int updateRequestOutstanding = 0;
|
||||
bool vuUpdateDropped = false;
|
||||
|
||||
@@ -1359,7 +1387,8 @@ public:
|
||||
Send("onControlChanged", body);
|
||||
}
|
||||
|
||||
class DeferredValue {
|
||||
class DeferredValue
|
||||
{
|
||||
public:
|
||||
int64_t instanceId;
|
||||
std::string symbol;
|
||||
@@ -1369,11 +1398,12 @@ public:
|
||||
std::vector<DeferredValue> deferredValues;
|
||||
bool midiValueChangedOutstanding = false;
|
||||
|
||||
|
||||
virtual void OnMidiValueChanged(int64_t instanceId, const std::string&symbol, float value) {
|
||||
virtual void OnMidiValueChanged(int64_t instanceId, const std::string &symbol, float value)
|
||||
{
|
||||
if (midiValueChangedOutstanding)
|
||||
{
|
||||
for (size_t i = 0; i < deferredValues.size(); ++i) {
|
||||
for (size_t i = 0; i < deferredValues.size(); ++i)
|
||||
{
|
||||
auto &deferredValue = deferredValues[i];
|
||||
if (deferredValue.instanceId == instanceId && deferredValue.symbol == symbol)
|
||||
{
|
||||
@@ -1381,37 +1411,39 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
DeferredValue newValue {instanceId,symbol,value};
|
||||
DeferredValue newValue{instanceId, symbol, value};
|
||||
deferredValues.push_back(newValue);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
midiValueChangedOutstanding = true;
|
||||
ControlChangedBody body;
|
||||
body.clientId_ = -1;
|
||||
body.instanceId_ = instanceId;
|
||||
body.symbol_ = symbol;
|
||||
body.value_ = value;
|
||||
Request<bool>("onMidiValueChanged", body,
|
||||
[this] (const bool& value)
|
||||
{
|
||||
this->midiValueChangedOutstanding = false;
|
||||
if (this->deferredValues.size() != 0)
|
||||
Request<bool>(
|
||||
"onMidiValueChanged", body,
|
||||
[this](const bool &value)
|
||||
{
|
||||
DeferredValue value = deferredValues[0];
|
||||
deferredValues.erase(deferredValues.begin());
|
||||
this->OnMidiValueChanged(value.instanceId,value.symbol,value.value);
|
||||
}
|
||||
this->midiValueChangedOutstanding = false;
|
||||
if (this->deferredValues.size() != 0)
|
||||
{
|
||||
DeferredValue value = deferredValues[0];
|
||||
deferredValues.erase(deferredValues.begin());
|
||||
this->OnMidiValueChanged(value.instanceId, value.symbol, value.value);
|
||||
}
|
||||
},
|
||||
[](const std::exception &e) {
|
||||
|
||||
},
|
||||
[] (const std::exception &e) {
|
||||
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int outstandingNotifyAtomOutputs = 0;
|
||||
|
||||
class PendingNotifyAtomOutput {
|
||||
class PendingNotifyAtomOutput
|
||||
{
|
||||
public:
|
||||
int64_t clientHandle;
|
||||
uint64_t instanceId;
|
||||
@@ -1421,8 +1453,8 @@ public:
|
||||
|
||||
std::vector<PendingNotifyAtomOutput> pendingNotifyAtomOutputs;
|
||||
|
||||
|
||||
void OnAckNotifyAtomOutput() {
|
||||
void OnAckNotifyAtomOutput()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(subscriptionMutex);
|
||||
if (--outstandingNotifyAtomOutputs <= 0)
|
||||
{
|
||||
@@ -1436,12 +1468,11 @@ public:
|
||||
t.instanceId,
|
||||
t.atomType,
|
||||
t.json);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnNotifyAtomOutput(int64_t clientHandle,uint64_t instanceId,const std::string&atomType, const std::string&atomJson)
|
||||
virtual void OnNotifyAtomOutput(int64_t clientHandle, uint64_t instanceId, const std::string &atomType, const std::string &atomJson)
|
||||
{
|
||||
NotifyAtomOutputBody body;
|
||||
body.clientHandle_ = clientHandle;
|
||||
@@ -1462,53 +1493,53 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
pendingNotifyAtomOutputs.push_back(PendingNotifyAtomOutput{ clientHandle, instanceId,atomType,atomJson });
|
||||
pendingNotifyAtomOutputs.push_back(PendingNotifyAtomOutput{clientHandle, instanceId, atomType, atomJson});
|
||||
return;
|
||||
}
|
||||
++outstandingNotifyAtomOutputs;
|
||||
}
|
||||
|
||||
Request<bool>("onNotifyAtomOut",body,
|
||||
[this] (const bool& value)
|
||||
|
||||
Request<bool>(
|
||||
"onNotifyAtomOut", body,
|
||||
[this](const bool &value)
|
||||
{
|
||||
this->OnAckNotifyAtomOutput();
|
||||
},
|
||||
[] (const std::exception &e) {
|
||||
|
||||
}
|
||||
);
|
||||
[](const std::exception &e) {
|
||||
|
||||
});
|
||||
}
|
||||
virtual void OnNotifyMidiListener(int64_t clientHandle, bool isNote, uint8_t noteOrControl)
|
||||
virtual void OnNotifyMidiListener(int64_t clientHandle, bool isNote, uint8_t noteOrControl)
|
||||
{
|
||||
NotifyMidiListenerBody body;
|
||||
body.clientHandle_ = clientHandle;
|
||||
body.isNote_ = isNote;
|
||||
body.noteOrControl_ = noteOrControl;
|
||||
|
||||
Send("onNotifyMidiListener",body);
|
||||
Send("onNotifyMidiListener", body);
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void OnBankIndexChanged(const BankIndex& bankIndex)
|
||||
virtual void OnBankIndexChanged(const BankIndex &bankIndex)
|
||||
{
|
||||
Send("onBanksChanged",bankIndex);
|
||||
Send("onBanksChanged", bankIndex);
|
||||
}
|
||||
|
||||
virtual void OnJackServerSettingsChanged(const JackServerSettings& jackServerSettings)
|
||||
virtual void OnJackServerSettingsChanged(const JackServerSettings &jackServerSettings)
|
||||
{
|
||||
Send("onJackServerSettingsChanged",jackServerSettings);
|
||||
Send("onJackServerSettingsChanged", jackServerSettings);
|
||||
}
|
||||
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) {
|
||||
Send("onWifiConfigSettingsChanged",wifiConfigSettings);
|
||||
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings &wifiConfigSettings)
|
||||
{
|
||||
Send("onWifiConfigSettingsChanged", wifiConfigSettings);
|
||||
}
|
||||
|
||||
virtual void OnWifiDirectConfigSettingsChanged(const WifiDirectConfigSettings&wifiConfigSettings) {
|
||||
Send("onWifiDirectConfigSettingsChanged",wifiConfigSettings);
|
||||
virtual void OnWifiDirectConfigSettingsChanged(const WifiDirectConfigSettings &wifiConfigSettings)
|
||||
{
|
||||
Send("onWifiDirectConfigSettingsChanged", wifiConfigSettings);
|
||||
}
|
||||
virtual void OnGovernorSettingsChanged(const std::string& governor) {
|
||||
Send("onGovernorSettingsChanged",governor);
|
||||
virtual void OnGovernorSettingsChanged(const std::string &governor)
|
||||
{
|
||||
Send("onGovernorSettingsChanged", governor);
|
||||
}
|
||||
|
||||
virtual void OnPedalBoardChanged(int64_t clientId, const PedalBoard &pedalBoard)
|
||||
@@ -1519,7 +1550,6 @@ public:
|
||||
Send("onPedalBoardChanged", body);
|
||||
}
|
||||
|
||||
|
||||
virtual void OnItemEnabledChanged(int64_t clientId, int64_t pedalItemId, bool enabled)
|
||||
{
|
||||
PedalBoardItemEnabledBody body;
|
||||
@@ -1564,21 +1594,22 @@ std::shared_ptr<ISocketFactory> pipedal::MakePiPedalSocketFactory(PiPedalModel &
|
||||
return std::make_shared<PiPedalSocketFactory>(model);
|
||||
}
|
||||
|
||||
|
||||
void PiPedalSocketHandler::RequestShutdown(bool restart)
|
||||
{
|
||||
if (GetAdminClient().CanUseShutdownClient())
|
||||
{
|
||||
GetAdminClient().RequestShutdown(restart);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// ONLY works when interactively logged in.
|
||||
std::stringstream s;
|
||||
s << "/usr/sbin/shutdown ";
|
||||
if (restart)
|
||||
{
|
||||
s << "-r";
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "-P";
|
||||
}
|
||||
@@ -1587,9 +1618,12 @@ void PiPedalSocketHandler::RequestShutdown(bool restart)
|
||||
if (sysExec(s.str().c_str()) != EXIT_SUCCESS)
|
||||
{
|
||||
Lv2Log::error("shutdown failed.");
|
||||
if (restart) {
|
||||
if (restart)
|
||||
{
|
||||
throw new PiPedalStateException("Restart request failed.");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new PiPedalStateException("Shutdown request failed.");
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -655,15 +655,15 @@ int main(int argc, char *argv[])
|
||||
auto devices = model.GetAlsaDevices();
|
||||
bool firstMessage = true;
|
||||
bool found = false;
|
||||
if (!HasAlsaDevice(devices, serverSettings.GetAlsaDevice()))
|
||||
if (!HasAlsaDevice(devices, serverSettings.GetAlsaInputDevice()))
|
||||
{
|
||||
if (firstMessage) Lv2Log::info(SS("Waiting for ALSA device " << serverSettings.GetAlsaDevice() << " to come online..."));
|
||||
if (firstMessage) Lv2Log::info(SS("Waiting for ALSA device " << serverSettings.GetAlsaInputDevice() << " to come online..."));
|
||||
firstMessage = false;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
sleep(3);
|
||||
devices = model.GetAlsaDevices();
|
||||
if (HasAlsaDevice(devices, serverSettings.GetAlsaDevice()))
|
||||
if (HasAlsaDevice(devices, serverSettings.GetAlsaInputDevice()))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
@@ -673,9 +673,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
Lv2Log::info(SS("Found ALSA device " << serverSettings.GetAlsaDevice() << "."));
|
||||
Lv2Log::info(SS("Found ALSA device " << serverSettings.GetAlsaInputDevice() << "."));
|
||||
} else {
|
||||
Lv2Log::info(SS("ALSA device " << serverSettings.GetAlsaDevice() << " not found."));
|
||||
Lv2Log::info(SS("ALSA device " << serverSettings.GetAlsaInputDevice() << " not found."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user