Skip to content

Commit

Permalink
Tweak ALSA nperiod setting, fallback to nearest
Browse files Browse the repository at this point in the history
This is mainly for RME RayDAT that has a fixed buffersize of 16k:

  dev_name : hw:HDSPMxc2f6c5,0
  channels : 36
  min_rate : 32000
  max_rate : 192000
  min_bufz : 16384
  max_bufz : 16384
  min_nper : 4
  max_nper : 512

However nperiod configuration determines the effective latency
regardless.

This is similar to https://github.com/jackaudio/jack1/blob/master/drivers/alsa/alsa_driver.c#L476-L486
  • Loading branch information
x42 committed Apr 29, 2020
1 parent 6eb48e4 commit 3a6a9cf
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 38 deletions.
4 changes: 2 additions & 2 deletions libs/ardouralsautil/deviceparams.cc
Expand Up @@ -115,8 +115,8 @@ ARDOUR::get_alsa_device_parameters (const char* device_name, const bool play, AL
fprintf (stdout, " channels : %u\n", nfo->max_channels);
fprintf (stdout, " min_rate : %u\n", nfo->min_rate);
fprintf (stdout, " max_rate : %u\n", nfo->max_rate);
fprintf (stdout, " min_psiz : %lu\n", nfo->min_size);
fprintf (stdout, " max_psiz : %lu\n", nfo->max_size);
fprintf (stdout, " min_psiz : %lu\n", min_psiz);
fprintf (stdout, " max_psiz : %lu\n", max_psiz);
fprintf (stdout, " min_bufz : %lu\n", min_bufz);
fprintf (stdout, " max_bufz : %lu\n", max_bufz);
fprintf (stdout, " min_nper : %d\n", nfo->min_nper);
Expand Down
16 changes: 7 additions & 9 deletions libs/backends/alsa/alsa_audiobackend.cc
Expand Up @@ -270,25 +270,23 @@ std::vector<uint32_t>
AlsaAudioBackend::available_period_sizes (const std::string& driver, const std::string& device) const
{
std::vector<uint32_t> ps;
ps.push_back (2);

ALSADeviceInfo* nfo = NULL;
if (device == get_standard_device_name(DeviceNone)) {
return ps;
}

if (device == _output_audio_device && _output_audio_device_info.valid) {
nfo = &_output_audio_device_info;
} else {
ps.push_back (2);
return ps;
}

if (nfo->min_nper == 2) {
ps.push_back (2);
if (nfo->max_nper >= 3) {
if (nfo->max_nper > 2) {
ps.push_back (3);
}
if (nfo->max_nper > 3) {
ps.push_back (nfo->min_nper);
}
} else {
ps.push_back (nfo->min_nper);
ps.push_back (3);
}

return ps;
Expand Down
41 changes: 16 additions & 25 deletions libs/backends/alsa/zita-alsa-pcmi.cc
Expand Up @@ -486,11 +486,7 @@ void Alsa_pcmi::initialise (const char *play_name, const char *capt_name, const
}
if (snd_pcm_hw_params_get_periods (_play_hwpar, &nfrag, &dir) || (nfrag != _play_nfrag) || dir)
{
if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi: can't get requested number of periods for playback.\n");
if ((_debug & FRAG_NEAR) == 0) {
_state = -5;
return;
}
if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi warning: requested %u periods for playback, using %u.\n", _play_nfrag, nfrag);
}

snd_pcm_hw_params_get_format (_play_hwpar, &_play_format);
Expand Down Expand Up @@ -776,29 +772,24 @@ int Alsa_pcmi::set_hwpar (snd_pcm_t *handle, snd_pcm_hw_params_t *hwpar, const
sname, _fsize);
return -4;
}
if ((_debug & FRAG_NEAR)) {
unsigned int nf = nfrag;
snd_pcm_hw_params_set_periods_min (handle, hwpar, &nf, NULL);
if (nf > nfrag) {
nfrag = nf;
}
if (snd_pcm_hw_params_set_periods_near (handle, hwpar, &nfrag, NULL) < 0) {
if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi: can't set %s periods to %u.\n",
sname, nfrag);
return -5;
}
} else {
if (snd_pcm_hw_params_set_periods (handle, hwpar, nfrag, 0) < 0)
{
if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi: can't set %s periods to %u.\n",
sname, nfrag);
return -5;
}

unsigned int nf = nfrag;
snd_pcm_hw_params_set_periods_min (handle, hwpar, &nf, NULL);
if (nf < nfrag) {
nf = nfrag;
}
if (snd_pcm_hw_params_set_periods_near (handle, hwpar, &nf, NULL) < 0) {
if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi: can't set %s periods to %u (requested %u).\n",
sname, nf, nfrag);
return -5;
}
if (snd_pcm_hw_params_set_buffer_size (handle, hwpar, _fsize * nfrag) < 0)

if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi: use %d periods for %s ((requested %u).\n", nf, sname, nfrag);

if (snd_pcm_hw_params_set_buffer_size (handle, hwpar, _fsize * nf) < 0)
{
if (_debug & DEBUG_INIT) fprintf (stderr, "Alsa_pcmi: can't set %s buffer length to %lu.\n",
sname, _fsize * nfrag);
sname, _fsize * nf);
return -4;
}
if (snd_pcm_hw_params (handle, hwpar) < 0)
Expand Down
3 changes: 1 addition & 2 deletions libs/backends/alsa/zita-alsa-pcmi.h
Expand Up @@ -60,8 +60,7 @@ class Alsa_pcmi
DEBUG_DATA = 8,
DEBUG_ALL = 15,
FORCE_16B = 256,
FORCE_2CH = 512,
FRAG_NEAR = 1024
FORCE_2CH = 512
};

void printinfo (void);
Expand Down

0 comments on commit 3a6a9cf

Please sign in to comment.