Devices with only I or O Fix
Added new fields to track ALSA device capabilities, letting the application know whether a device supports capture or playback Updated serialization to include the new flags in the JSON data exchanged with the UI Modified the dummy driver so test devices always indicate capture and playback support Adjusted the TypeScript model and dialog to filter device choices based on the new flags, ensuring only valid options appear in selectors
This commit is contained in:
@@ -517,6 +517,8 @@ namespace pipedal
|
|||||||
result.sampleRates_.push_back(48000);
|
result.sampleRates_.push_back(48000);
|
||||||
result.minBufferSize_ = 16;
|
result.minBufferSize_ = 16;
|
||||||
result.maxBufferSize_ = 1024;
|
result.maxBufferSize_ = 1024;
|
||||||
|
result.supportsCapture_ = true;
|
||||||
|
result.supportsPlayback_ = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-16
@@ -97,20 +97,16 @@ std::vector<AlsaDeviceInfo> PiPedalAlsaDevices::GetAlsaDevices()
|
|||||||
info.name_ = snd_ctl_card_info_get_name(alsaInfo);
|
info.name_ = snd_ctl_card_info_get_name(alsaInfo);
|
||||||
info.longName_ = snd_ctl_card_info_get_longname(alsaInfo);
|
info.longName_ = snd_ctl_card_info_get_longname(alsaInfo);
|
||||||
|
|
||||||
snd_pcm_t *hDevice = nullptr;
|
snd_pcm_t *captureDevice = nullptr;
|
||||||
|
snd_pcm_t *playbackDevice = nullptr;
|
||||||
|
bool captureOk = snd_pcm_open(&captureDevice, cardId.c_str(), SND_PCM_STREAM_CAPTURE, 0) == 0;
|
||||||
|
bool playbackOk = snd_pcm_open(&playbackDevice, cardId.c_str(), SND_PCM_STREAM_PLAYBACK, 0) == 0;
|
||||||
|
info.supportsCapture_ = captureOk;
|
||||||
|
info.supportsPlayback_ = playbackOk;
|
||||||
|
|
||||||
// must support capture AND playback
|
if (captureOk || playbackOk)
|
||||||
err = snd_pcm_open(&hDevice, cardId.c_str(), SND_PCM_STREAM_CAPTURE, 0);
|
|
||||||
if (err == 0)
|
|
||||||
{
|
|
||||||
snd_pcm_close(hDevice);
|
|
||||||
}
|
|
||||||
if (err == 0)
|
|
||||||
{
|
|
||||||
err = snd_pcm_open(&hDevice, cardId.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
|
|
||||||
}
|
|
||||||
if (err == 0)
|
|
||||||
{
|
{
|
||||||
|
snd_pcm_t *hDevice = captureOk ? captureDevice : playbackDevice;
|
||||||
snd_pcm_hw_params_t *params = nullptr;
|
snd_pcm_hw_params_t *params = nullptr;
|
||||||
err = snd_pcm_hw_params_malloc(¶ms);
|
err = snd_pcm_hw_params_malloc(¶ms);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
@@ -151,15 +147,25 @@ std::vector<AlsaDeviceInfo> PiPedalAlsaDevices::GetAlsaDevices()
|
|||||||
|
|
||||||
info.minBufferSize_ = (uint32_t)minBufferSize;
|
info.minBufferSize_ = (uint32_t)minBufferSize;
|
||||||
info.maxBufferSize_ = (uint32_t)maxBufferSize;
|
info.maxBufferSize_ = (uint32_t)maxBufferSize;
|
||||||
cacheDevice(info.name_, info);
|
|
||||||
result.push_back(info);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params != nullptr)
|
if (params != nullptr)
|
||||||
snd_pcm_hw_params_free(params);
|
snd_pcm_hw_params_free(params);
|
||||||
snd_pcm_close(hDevice);
|
if (captureOk)
|
||||||
}
|
snd_pcm_close(captureDevice);
|
||||||
|
if (playbackOk && playbackDevice != captureDevice)
|
||||||
|
snd_pcm_close(playbackDevice);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
cacheDevice(info.name_, info);
|
||||||
|
result.push_back(info);
|
||||||
|
}
|
||||||
|
else if (getCachedDevice(info.name_, &info))
|
||||||
|
{
|
||||||
|
result.push_back(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (getCachedDevice(info.name_, &info))
|
if (getCachedDevice(info.name_, &info))
|
||||||
@@ -480,6 +486,8 @@ JSON_MAP_REFERENCE(AlsaDeviceInfo, longName)
|
|||||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, sampleRates)
|
JSON_MAP_REFERENCE(AlsaDeviceInfo, sampleRates)
|
||||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, minBufferSize)
|
JSON_MAP_REFERENCE(AlsaDeviceInfo, minBufferSize)
|
||||||
JSON_MAP_REFERENCE(AlsaDeviceInfo, maxBufferSize)
|
JSON_MAP_REFERENCE(AlsaDeviceInfo, maxBufferSize)
|
||||||
|
JSON_MAP_REFERENCE(AlsaDeviceInfo, supportsCapture)
|
||||||
|
JSON_MAP_REFERENCE(AlsaDeviceInfo, supportsPlayback)
|
||||||
JSON_MAP_END()
|
JSON_MAP_END()
|
||||||
|
|
||||||
JSON_MAP_BEGIN(AlsaMidiDeviceInfo)
|
JSON_MAP_BEGIN(AlsaMidiDeviceInfo)
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ namespace pipedal {
|
|||||||
std::string longName_;
|
std::string longName_;
|
||||||
std::vector<uint32_t> sampleRates_;
|
std::vector<uint32_t> sampleRates_;
|
||||||
uint32_t minBufferSize_ = 0,maxBufferSize_ = 0;
|
uint32_t minBufferSize_ = 0,maxBufferSize_ = 0;
|
||||||
|
bool supportsCapture_ = false;
|
||||||
|
bool supportsPlayback_ = false;
|
||||||
|
|
||||||
bool isDummyDevice() const {
|
bool isDummyDevice() const {
|
||||||
return id_.starts_with("dummy:");
|
return id_.starts_with("dummy:");
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ export default class AlsaDeviceInfo {
|
|||||||
this.sampleRates = input.sampleRates as number[];
|
this.sampleRates = input.sampleRates as number[];
|
||||||
this.minBufferSize = input.minBufferSize;
|
this.minBufferSize = input.minBufferSize;
|
||||||
this.maxBufferSize = input.maxBufferSize;
|
this.maxBufferSize = input.maxBufferSize;
|
||||||
|
this.supportsCapture = input.supportsCapture ? true : false;
|
||||||
|
this.supportsPlayback = input.supportsPlayback ? true : false;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
static deserialize_array(input: any): AlsaDeviceInfo[]
|
static deserialize_array(input: any): AlsaDeviceInfo[]
|
||||||
@@ -62,5 +64,7 @@ export default class AlsaDeviceInfo {
|
|||||||
longName: string = "";
|
longName: string = "";
|
||||||
sampleRates: number[] = [];
|
sampleRates: number[] = [];
|
||||||
minBufferSize: number = 0;
|
minBufferSize: number = 0;
|
||||||
maxBufferSize: number = 0;
|
maxBufferSize: number = 0;
|
||||||
|
supportsCapture: boolean = false;
|
||||||
|
supportsPlayback: boolean = false;
|
||||||
};
|
};
|
||||||
@@ -220,8 +220,8 @@ function isOkEnabled(jackServerSettings: JackServerSettings, alsaDevices?: AlsaD
|
|||||||
{
|
{
|
||||||
if (!jackServerSettings.valid) return false;
|
if (!jackServerSettings.valid) return false;
|
||||||
if (!alsaDevices) return false;
|
if (!alsaDevices) return false;
|
||||||
const inDevice = alsaDevices.find(d => d.id === jackServerSettings.alsaInputDevice);
|
const inDevice = alsaDevices.find(d => d.id === jackServerSettings.alsaInputDevice && d.supportsCapture);
|
||||||
const outDevice = alsaDevices.find(d => d.id === jackServerSettings.alsaOutputDevice);
|
const outDevice = alsaDevices.find(d => d.id === jackServerSettings.alsaOutputDevice && d.supportsPlayback);
|
||||||
if (!inDevice || !outDevice) return false;
|
if (!inDevice || !outDevice) return false;
|
||||||
|
|
||||||
const deviceBufferSize = jackServerSettings.bufferSize * jackServerSettings.numberOfBuffers;
|
const deviceBufferSize = jackServerSettings.bufferSize * jackServerSettings.numberOfBuffers;
|
||||||
@@ -289,15 +289,24 @@ const JackServerSettingsDialog = withStyles(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inDevice = alsaDevices.find(d => d.id === result.alsaInputDevice);
|
let inDevice = alsaDevices.find(d => d.id === result.alsaInputDevice && d.supportsCapture);
|
||||||
let outDevice = alsaDevices.find(d => d.id === result.alsaOutputDevice);
|
let outDevice = alsaDevices.find(d => d.id === result.alsaOutputDevice && d.supportsPlayback);
|
||||||
if (!inDevice) {
|
if (!inDevice) {
|
||||||
inDevice = alsaDevices[0];
|
inDevice = alsaDevices.find(d => d.supportsCapture);
|
||||||
result.alsaInputDevice = inDevice.id;
|
if (inDevice) {
|
||||||
|
result.alsaInputDevice = inDevice.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!outDevice) {
|
if (!outDevice) {
|
||||||
outDevice = alsaDevices[0];
|
outDevice = alsaDevices.find(d => d.supportsPlayback);
|
||||||
result.alsaOutputDevice = outDevice.id;
|
if (outDevice) {
|
||||||
|
result.alsaOutputDevice = outDevice.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inDevice || !outDevice) {
|
||||||
|
result.valid = false;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.sampleRate === 0) result.sampleRate = 48000;
|
if (result.sampleRate === 0) result.sampleRate = 48000;
|
||||||
@@ -467,9 +476,9 @@ const JackServerSettingsDialog = withStyles(
|
|||||||
disabled={!this.state.alsaDevices || this.state.alsaDevices.length === 0}
|
disabled={!this.state.alsaDevices || this.state.alsaDevices.length === 0}
|
||||||
style={{ width: 220 }}
|
style={{ width: 220 }}
|
||||||
>
|
>
|
||||||
{this.state.alsaDevices?.map(d => (
|
{this.state.alsaDevices?.filter(d => d.supportsCapture).map(d => (
|
||||||
<MenuItem key={d.id} value={d.id}>{d.name}</MenuItem>
|
<MenuItem key={d.id} value={d.id}>{d.name}</MenuItem>
|
||||||
)) || <MenuItem value="" disabled>Loading...</MenuItem>}
|
)) || <MenuItem value="" disabled>Loading...</MenuItem>}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
@@ -483,8 +492,8 @@ const JackServerSettingsDialog = withStyles(
|
|||||||
disabled={!this.state.alsaDevices || this.state.alsaDevices.length === 0}
|
disabled={!this.state.alsaDevices || this.state.alsaDevices.length === 0}
|
||||||
style={{ width: 220 }}
|
style={{ width: 220 }}
|
||||||
>
|
>
|
||||||
{this.state.alsaDevices?.map(d => (
|
{this.state.alsaDevices?.filter(d => d.supportsPlayback).map(d => (
|
||||||
<MenuItem key={d.id} value={d.id}>{d.name}</MenuItem>
|
<MenuItem key={d.id} value={d.id}>{d.name}</MenuItem>
|
||||||
)) || <MenuItem value="" disabled>Loading...</MenuItem>}
|
)) || <MenuItem value="" disabled>Loading...</MenuItem>}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|||||||
Reference in New Issue
Block a user