mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: Disable rate matching for the same card
Add a clock name to the clock, remove the old api/clock_id. This makes it easier to add descriptive names Place the alsa card number in the clock name. Check the clock name of the master clock and if it matches our own clock, disable rate matching.
This commit is contained in:
parent
54f6834de4
commit
5383782336
5 changed files with 33 additions and 8 deletions
|
|
@ -123,8 +123,9 @@ struct spa_io_range {
|
|||
struct spa_io_clock {
|
||||
uint32_t flags; /**< clock flags */
|
||||
uint32_t id; /**< unique clock id, set by application */
|
||||
uint32_t api; /**< api of the clock */
|
||||
uint32_t clock_id; /**< api specific clock id */
|
||||
char name[64]; /**< clock name prefixed with API, set by node. The clock name
|
||||
* is unique per clock and can be used to check if nodes
|
||||
* share the same clock. */
|
||||
uint64_t nsec; /**< time in nanoseconds against monotonic clock */
|
||||
uint64_t count; /**< a media specific counter. Can be used to detect
|
||||
* gaps in the media. It usually represents the amount
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
|
|||
|
||||
switch (id) {
|
||||
case SPA_IO_Clock:
|
||||
if (size > 0 && size < sizeof(struct spa_io_clock))
|
||||
return -EINVAL;
|
||||
this->clock = data;
|
||||
break;
|
||||
case SPA_IO_Position:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ static int spa_alsa_open(struct state *state)
|
|||
{
|
||||
int err;
|
||||
struct props *props = &state->props;
|
||||
snd_pcm_info_t *pcminfo;
|
||||
|
||||
if (state->opened)
|
||||
return 0;
|
||||
|
|
@ -42,6 +43,16 @@ static int spa_alsa_open(struct state *state)
|
|||
|
||||
state->timerfd = err;
|
||||
|
||||
snd_pcm_info_alloca(&pcminfo);
|
||||
snd_pcm_info(state->hndl, pcminfo);
|
||||
|
||||
/* we would love to use the sync_id but it always returns 0, so use the
|
||||
* card id for now */
|
||||
state->card = snd_pcm_info_get_card(pcminfo);
|
||||
if (state->clock) {
|
||||
snprintf(state->clock->name, sizeof(state->clock->name),
|
||||
"api.alsa.%d", state->card);
|
||||
}
|
||||
state->opened = true;
|
||||
state->sample_count = 0;
|
||||
state->sample_time = 0;
|
||||
|
|
@ -608,7 +619,7 @@ static int get_status(struct state *state, snd_pcm_uframes_t *delay, snd_pcm_ufr
|
|||
|
||||
*target = state->last_threshold;
|
||||
|
||||
if (state->slaved && state->rate_match) {
|
||||
if (state->matching && state->rate_match) {
|
||||
state->delay = state->rate_match->delay;
|
||||
state->read_size = state->rate_match->size;
|
||||
/* We try to compensate for the latency introduced by rate matching
|
||||
|
|
@ -618,6 +629,8 @@ static int get_status(struct state *state, snd_pcm_uframes_t *delay, snd_pcm_ufr
|
|||
if (*target <= state->delay + 48)
|
||||
state->delay = SPA_MAX(0, (int)(*target - 48 - state->delay));
|
||||
*target -= state->delay;
|
||||
} else {
|
||||
state->delay = state->read_size = 0;
|
||||
}
|
||||
|
||||
if (state->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||
|
|
@ -678,7 +691,7 @@ static int update_time(struct state *state, uint64_t nsec, snd_pcm_sframes_t del
|
|||
else
|
||||
state->rate_match->rate = SPA_CLAMP(1.0/corr, 0.95, 1.05);
|
||||
|
||||
SPA_FLAG_UPDATE(state->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE, slave);
|
||||
SPA_FLAG_UPDATE(state->rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE, state->matching);
|
||||
}
|
||||
|
||||
state->next_time += state->threshold / corr * 1e9 / state->rate;
|
||||
|
|
@ -1137,8 +1150,14 @@ int spa_alsa_start(struct state *state)
|
|||
return 0;
|
||||
|
||||
state->slaved = is_slaved(state);
|
||||
state->matching = state->slaved;
|
||||
|
||||
if (state->position) {
|
||||
int card;
|
||||
if (sscanf(state->position->clock.name, "api.alsa.%d", &card) == 1 &&
|
||||
card == state->card) {
|
||||
state->matching = false;
|
||||
}
|
||||
state->duration = state->position->clock.duration;
|
||||
state->rate_denom = state->position->clock.rate.denom;
|
||||
}
|
||||
|
|
@ -1154,8 +1173,9 @@ int spa_alsa_start(struct state *state)
|
|||
init_loop(state);
|
||||
state->safety = 0.0;
|
||||
|
||||
spa_log_debug(state->log, NAME" %p: start %d duration:%d rate:%d slave:%d",
|
||||
state, state->threshold, state->duration, state->rate_denom, state->slaved);
|
||||
spa_log_debug(state->log, NAME" %p: start %d duration:%d rate:%d slave:%d match:%d",
|
||||
state, state->threshold, state->duration, state->rate_denom,
|
||||
state->slaved, state->matching);
|
||||
|
||||
CHECK(set_swparams(state), "swparams");
|
||||
if (SPA_UNLIKELY(spa_log_level_enabled(state->log, SPA_LOG_LEVEL_DEBUG)))
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ struct state {
|
|||
|
||||
bool opened;
|
||||
snd_pcm_t *hndl;
|
||||
int card;
|
||||
|
||||
bool have_format;
|
||||
struct spa_audio_info current_format;
|
||||
|
|
@ -135,6 +136,7 @@ struct state {
|
|||
unsigned int alsa_sync:1;
|
||||
unsigned int alsa_recovering:1;
|
||||
unsigned int slaved:1;
|
||||
unsigned int matching:1;
|
||||
|
||||
int64_t sample_count;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static void test_io_abi(void)
|
|||
spa_assert(sizeof(struct spa_io_buffers) == 8);
|
||||
spa_assert(sizeof(struct spa_io_memory) == 16);
|
||||
spa_assert(sizeof(struct spa_io_range) == 16);
|
||||
spa_assert(sizeof(struct spa_io_clock) == 80);
|
||||
spa_assert(sizeof(struct spa_io_clock) == 136);
|
||||
spa_assert(sizeof(struct spa_io_latency) == 24);
|
||||
spa_assert(sizeof(struct spa_io_sequence) == 16);
|
||||
spa_assert(sizeof(struct spa_io_segment_bar) == 96);
|
||||
|
|
@ -56,7 +56,7 @@ static void test_io_abi(void)
|
|||
spa_assert(SPA_IO_POSITION_STATE_STARTING == 1);
|
||||
spa_assert(SPA_IO_POSITION_STATE_RUNNING == 2);
|
||||
|
||||
spa_assert(sizeof(struct spa_io_position) == 1952);
|
||||
spa_assert(sizeof(struct spa_io_position) == 2008);
|
||||
spa_assert(sizeof(struct spa_io_rate_match) == 48);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue