summaryrefslogtreecommitdiff
path: root/sound/core/pcm_lib.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2024-06-25 19:25:46 +0200
committerTakashi Iwai <tiwai@suse.de>2024-07-02 09:53:21 +0200
commitf05c1ffc274516ef101d2e0f860bcb9b08c6c622 (patch)
tree6e57abd9c85b75d301ad83377b22aa86ad1d3344 /sound/core/pcm_lib.c
parent5b707581c072bcef086ef4c122a2ea81470a1027 (diff)
ALSA: pcm: reinvent the stream synchronization ID API
Until the commit e11f0f90a626 ("ALSA: pcm: remove SNDRV_PCM_IOCTL1_INFO internal command"), there was a possibility to pass information about the synchronized streams to the user space. The mentioned commit removed blindly the appropriate code with an irrelevant comment. The revert may be appropriate, but since this API was lost for several years without any complains, it's time to improve it. The hardware parameters may change the used stream clock source (e.g. USB hardware) so move this synchronization ID to hw_params as read-only field. It seems that pipewire can benefit from this API (disable adaptive resampling for perfectly synchronized PCM streams) now. Note that the contents of ID is not supposed to be used for direct comparison with a specific byte sequence. The "empty" case is when all bytes are zero (driver does not offer this information) and all other cases must be only used for equal comparison among PCM streams (including different sound cards) if they are using identical hardware clock. Cc: Takashi Sakamoto <takaswie@kernel.org> Signed-off-by: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20240625172836.589380-2-perex@perex.cz
Diffstat (limited to 'sound/core/pcm_lib.c')
-rw-r--r--sound/core/pcm_lib.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 071c67cbc479..f64a03f79b01 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -525,10 +525,8 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- runtime->sync.id32[0] = substream->pcm->card->number;
- runtime->sync.id32[1] = -1;
- runtime->sync.id32[2] = -1;
- runtime->sync.id32[3] = -1;
+ *(__u32 *)runtime->sync = cpu_to_le32(substream->pcm->card->number);
+ memset(runtime->sync + 4, 0xff, sizeof(runtime->sync) - 4);
}
EXPORT_SYMBOL(snd_pcm_set_sync);
@@ -1811,6 +1809,25 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
}
/**
+ * is sync id (clock id) empty?
+ */
+static inline bool pcm_sync_empty(const unsigned char *sync)
+{
+ return sync[0] == 0 && sync[1] == 0 && sync[2] == 0 && sync[3] == 0 &&
+ sync[4] == 0 && sync[5] == 0 && sync[6] == 0 && sync[7] == 0;
+}
+
+static int snd_pcm_lib_ioctl_sync_id(struct snd_pcm_substream *substream,
+ void *arg)
+{
+ struct snd_pcm_hw_params *params = arg;
+
+ if (pcm_sync_empty(params->sync))
+ memcpy(params->sync, substream->runtime->sync, sizeof(params->sync));
+ return 0;
+}
+
+/**
* snd_pcm_lib_ioctl - a generic PCM ioctl callback
* @substream: the pcm substream instance
* @cmd: ioctl command
@@ -1831,6 +1848,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
return snd_pcm_lib_ioctl_channel_info(substream, arg);
case SNDRV_PCM_IOCTL1_FIFO_SIZE:
return snd_pcm_lib_ioctl_fifo_size(substream, arg);
+ case SNDRV_PCM_IOCTL1_SYNC_ID:
+ return snd_pcm_lib_ioctl_sync_id(substream, arg);
}
return -ENXIO;
}