Split IO dialog fixes.
This commit is contained in:
+17
-10
@@ -271,7 +271,7 @@ namespace pipedal
|
||||
auto inAvail = snd_pcm_avail_update(this->captureHandle);
|
||||
auto outAvail = snd_pcm_avail_update(this->playbackHandle);
|
||||
|
||||
auto total = inAvail + outAvail + framesInBuffer;
|
||||
auto total = (inAvail >= 0? inAvail: 0) + (outAvail >= 0 ? outAvail: 0) + framesInBuffer;
|
||||
bufferTraces[bufferTraceIndex++] = {
|
||||
time,
|
||||
inAvail,
|
||||
@@ -1180,11 +1180,13 @@ namespace pipedal
|
||||
throw std::runtime_error("Unable to restart the audio stream.");
|
||||
}
|
||||
int err;
|
||||
|
||||
if ((err = snd_pcm_start(captureHandle)) < 0)
|
||||
{
|
||||
Lv2Log::error(SS("Unable to restart ALSA capture: " << snd_strerror(err)));
|
||||
throw PiPedalStateException("Unable to restart ALSA capture.");
|
||||
}
|
||||
TraceBufferPositions(0,'+');
|
||||
audioRunning = true;
|
||||
}
|
||||
|
||||
@@ -1518,9 +1520,11 @@ namespace pipedal
|
||||
}
|
||||
snd_pcm_drain(capture_handle);
|
||||
FillOutputBuffer();
|
||||
TraceBufferPositions(framesRead, 'x');
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceBufferPositions(framesRead, 'z');
|
||||
Lv2Log::error(SS("Can't recover from ALSA output underrun. (" << snd_strerror(err) << ")"));
|
||||
throw PiPedalStateException(SS("Can't recover from ALSA output error. (" << snd_strerror(err) << ")"));
|
||||
}
|
||||
@@ -1621,7 +1625,7 @@ namespace pipedal
|
||||
// expand running status if neccessary.
|
||||
// deal with regular and sysex messages split across
|
||||
// buffer boundaries (but discard them)
|
||||
snd_pcm_sframes_t framesRead;
|
||||
snd_pcm_sframes_t framesRead = 0;
|
||||
|
||||
auto state = snd_pcm_state(handle);
|
||||
auto frame_bytes = this->captureFrameSize;
|
||||
@@ -2369,16 +2373,19 @@ namespace pipedal
|
||||
{
|
||||
auto&bufferTrace = bufferTraces[ix];
|
||||
|
||||
int64_t dt = (int64_t)bufferTrace.time - (int64_t)t0;
|
||||
if (bufferTrace.time != 0)
|
||||
{
|
||||
int64_t dt = (int64_t)bufferTrace.time - (int64_t)t0;
|
||||
|
||||
|
||||
cout << bufferTrace.code << " "
|
||||
<< fixed << setprecision(3) << dt*0.001
|
||||
<< " " << "inAvail: " << bufferTrace.inAvail
|
||||
<< " " << "outAvail: " << bufferTrace.outAvail
|
||||
<< " " << "bufferd: " << bufferTrace.buffered
|
||||
<< " " << "total: " << bufferTrace.total
|
||||
<< endl;
|
||||
cout << bufferTrace.code << " "
|
||||
<< fixed << setprecision(3) << dt*0.001
|
||||
<< " " << "inAvail: " << bufferTrace.inAvail
|
||||
<< " " << "outAvail: " << bufferTrace.outAvail
|
||||
<< " " << "buffered: " << bufferTrace.buffered
|
||||
<< " " << "total: " << bufferTrace.total
|
||||
<< endl;
|
||||
}
|
||||
|
||||
++ix;
|
||||
if (ix == bufferTraces.size())
|
||||
|
||||
+71
-64
@@ -108,102 +108,107 @@ std::vector<AlsaDeviceInfo> PiPedalAlsaDevices::GetAlsaDevices()
|
||||
info.cardId_ = cardNum;
|
||||
info.id_ = std::string("hw:") + snd_ctl_card_info_get_id(alsaInfo);
|
||||
const char *driver = snd_ctl_card_info_get_driver(alsaInfo);
|
||||
(void)driver;
|
||||
|
||||
info.name_ = snd_ctl_card_info_get_name(alsaInfo);
|
||||
info.longName_ = snd_ctl_card_info_get_longname(alsaInfo);
|
||||
|
||||
snd_pcm_t *captureDevice = nullptr;
|
||||
snd_pcm_t *playbackDevice = nullptr;
|
||||
bool captureOk = snd_pcm_open(&captureDevice, cardId.c_str(), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK) == 0;
|
||||
bool playbackOk = snd_pcm_open(&playbackDevice, cardId.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) == 0;
|
||||
Finally ffCaptureDevice{
|
||||
[captureDevice]
|
||||
{ if (captureDevice) snd_pcm_close(captureDevice); }};
|
||||
Finally ffPlaybackDevice{
|
||||
[playbackDevice]
|
||||
{ if (playbackDevice) snd_pcm_close(playbackDevice); }};
|
||||
// we can't read our own device if it's open so use data that gets
|
||||
// cached before we open audio devices.
|
||||
|
||||
info.supportsCapture_ = captureOk;
|
||||
info.supportsPlayback_ = playbackOk;
|
||||
|
||||
if (captureOk || playbackOk)
|
||||
AlsaDeviceInfo cachedInfo;
|
||||
if (getCachedDevice(info.name_, &cachedInfo))
|
||||
{
|
||||
snd_pcm_t *hDevice = captureOk ? captureDevice : playbackDevice;
|
||||
snd_pcm_hw_params_t *params = nullptr;
|
||||
err = snd_pcm_hw_params_malloc(¶ms);
|
||||
// may have been plugged into a different USB connector.
|
||||
cachedInfo.cardId_ = info.cardId_;
|
||||
cachedInfo.id_ = info.id_;
|
||||
result.push_back(cachedInfo);
|
||||
|
||||
if (err == 0)
|
||||
}
|
||||
else
|
||||
{
|
||||
snd_pcm_t *captureDevice = nullptr;
|
||||
snd_pcm_t *playbackDevice = nullptr;
|
||||
bool captureOk = snd_pcm_open(&captureDevice, cardId.c_str(), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK) == 0;
|
||||
bool playbackOk = snd_pcm_open(&playbackDevice, cardId.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) == 0;
|
||||
Finally ffCaptureDevice{
|
||||
[captureDevice]
|
||||
{ if (captureDevice) snd_pcm_close(captureDevice); }};
|
||||
Finally ffPlaybackDevice{
|
||||
[playbackDevice]
|
||||
{ if (playbackDevice) snd_pcm_close(playbackDevice); }};
|
||||
|
||||
info.supportsCapture_ = captureOk;
|
||||
info.supportsPlayback_ = playbackOk;
|
||||
|
||||
if (captureOk || playbackOk)
|
||||
{
|
||||
Finally ffParams{[params]
|
||||
{ snd_pcm_hw_params_free(params); }};
|
||||
snd_pcm_t *hDevice = captureOk ? captureDevice : playbackDevice;
|
||||
snd_pcm_hw_params_t *params = nullptr;
|
||||
err = snd_pcm_hw_params_malloc(¶ms);
|
||||
|
||||
err = snd_pcm_hw_params_any(hDevice, params);
|
||||
if (err == 0)
|
||||
{
|
||||
unsigned int minRate = 0, maxRate = 0;
|
||||
snd_pcm_uframes_t minBufferSize = 0, maxBufferSize = 0;
|
||||
int dir;
|
||||
Finally ffParams{[params]
|
||||
{ snd_pcm_hw_params_free(params); }};
|
||||
|
||||
err = snd_pcm_hw_params_get_rate_min(params, &minRate, &dir);
|
||||
err = snd_pcm_hw_params_any(hDevice, params);
|
||||
if (err == 0)
|
||||
{
|
||||
err = snd_pcm_hw_params_get_rate_max(params, &maxRate, &dir);
|
||||
unsigned int minRate = 0, maxRate = 0;
|
||||
snd_pcm_uframes_t minBufferSize = 0, maxBufferSize = 0;
|
||||
int dir;
|
||||
|
||||
err = snd_pcm_hw_params_get_rate_min(params, &minRate, &dir);
|
||||
if (err == 0)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(RATES) / sizeof(RATES[0]); ++i)
|
||||
err = snd_pcm_hw_params_get_rate_max(params, &maxRate, &dir);
|
||||
if (err == 0)
|
||||
{
|
||||
uint32_t rate = RATES[i];
|
||||
if (rate >= minRate && rate <= maxRate)
|
||||
for (size_t i = 0; i < sizeof(RATES) / sizeof(RATES[0]); ++i)
|
||||
{
|
||||
info.sampleRates_.push_back(rate);
|
||||
uint32_t rate = RATES[i];
|
||||
if (rate >= minRate && rate <= maxRate)
|
||||
{
|
||||
info.sampleRates_.push_back(rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Lv2Log::warning(SS("Failed to get maximum sample rate for device '" << info.name_ << "'."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Lv2Log::warning(SS("Failed to get maximum sample rate for device '" << info.name_ << "'."));
|
||||
Lv2Log::warning(SS("Failed to get minimum sample rate for device '" << info.name_ << "'."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Lv2Log::warning(SS("Failed to get minimum sample rate for device '" << info.name_ << "'."));
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
err = snd_pcm_hw_params_get_buffer_size_min(params, &minBufferSize);
|
||||
if (err == 0)
|
||||
{
|
||||
err = snd_pcm_hw_params_get_buffer_size_max(params, &maxBufferSize);
|
||||
err = snd_pcm_hw_params_get_buffer_size_min(params, &minBufferSize);
|
||||
if (err == 0)
|
||||
{
|
||||
err = snd_pcm_hw_params_get_buffer_size_max(params, &maxBufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err == 0)
|
||||
{
|
||||
if (minBufferSize < 16)
|
||||
if (err == 0)
|
||||
{
|
||||
minBufferSize = 16;
|
||||
}
|
||||
if (minBufferSize < 16)
|
||||
{
|
||||
minBufferSize = 16;
|
||||
}
|
||||
|
||||
info.minBufferSize_ = (uint32_t)minBufferSize;
|
||||
info.maxBufferSize_ = (uint32_t)maxBufferSize;
|
||||
info.minBufferSize_ = (uint32_t)minBufferSize;
|
||||
info.maxBufferSize_ = (uint32_t)maxBufferSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err == 0)
|
||||
{
|
||||
cacheDevice(info.name_, info);
|
||||
result.push_back(info);
|
||||
}
|
||||
else if (getCachedDevice(info.name_, &info))
|
||||
{
|
||||
result.push_back(info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getCachedDevice(info.name_, &info))
|
||||
{
|
||||
result.push_back(info);
|
||||
if (err == 0)
|
||||
{
|
||||
cacheDevice(info.name_, info);
|
||||
result.push_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -528,6 +533,8 @@ JSON_MAP_REFERENCE(AlsaDeviceInfo, longName)
|
||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, sampleRates)
|
||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, minBufferSize)
|
||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, maxBufferSize)
|
||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, supportsCapture)
|
||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, supportsPlayback)
|
||||
JSON_MAP_END()
|
||||
|
||||
JSON_MAP_BEGIN(AlsaMidiDeviceInfo)
|
||||
|
||||
+12
-4
@@ -237,6 +237,14 @@ void Storage::MaybeCopyDefaultPresets()
|
||||
}
|
||||
}
|
||||
|
||||
static void removeFileNoThrow(const std::filesystem::path &path)
|
||||
{
|
||||
try {
|
||||
fs::remove(path);
|
||||
} catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
}
|
||||
void Storage::UpgradeFactoryPresets()
|
||||
{
|
||||
auto presetsDirectory = this->GetPresetsDirectory();
|
||||
@@ -256,11 +264,11 @@ void Storage::UpgradeFactoryPresets()
|
||||
if (defaultConfigPresetsVersion.Version() > presetsVersion.Version() || defaultConfigPresetsVersion.Version() == 0)
|
||||
{
|
||||
// remove TooB ML README.md
|
||||
fs::remove("/usr/lib/lv2/ToobAmp.lv2/models/tones/README.md");
|
||||
fs::remove("/var/pipedal/audio_uploads/ToobMlModels/model.index");
|
||||
removeFileNoThrow("/usr/lib/lv2/ToobAmp.lv2/models/tones/README.md");
|
||||
removeFileNoThrow("/var/pipedal/audio_uploads/ToobMlModels/model.index");
|
||||
|
||||
fs::remove("/var/pipedal/audio_uploads/ToobMlModels/README.md");
|
||||
fs::remove("/var/pipedal/audio_uploads/ToobMlModels/model.index");
|
||||
removeFileNoThrow("/var/pipedal/audio_uploads/ToobMlModels/README.md");
|
||||
removeFileNoThrow("/var/pipedal/audio_uploads/ToobMlModels/model.index");
|
||||
|
||||
std::string name = "Factory Presets";
|
||||
BankFile newFactoryPresets;
|
||||
|
||||
Reference in New Issue
Block a user