Skip to content

Commit f05c1ff

Browse files
perexgtiwai
authored andcommitted
ALSA: pcm: reinvent the stream synchronization ID API
Until the commit e11f0f9 ("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 <[email protected]> Signed-off-by: Jaroslav Kysela <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent 5b70758 commit f05c1ff

File tree

5 files changed

+39
-13
lines changed

5 files changed

+39
-13
lines changed

include/sound/pcm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct snd_pcm_ops {
9393
#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
9494
/* 3 is absent slot. */
9595
#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
96+
#define SNDRV_PCM_IOCTL1_SYNC_ID 5
9697

9798
#define SNDRV_PCM_TRIGGER_STOP 0
9899
#define SNDRV_PCM_TRIGGER_START 1
@@ -401,7 +402,7 @@ struct snd_pcm_runtime {
401402
snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
402403
snd_pcm_uframes_t silence_filled; /* already filled part of silence area */
403404

404-
union snd_pcm_sync_id sync; /* hardware synchronization ID */
405+
unsigned char sync[16]; /* hardware synchronization ID */
405406

406407
/* -- mmap -- */
407408
struct snd_pcm_mmap_status *status;

include/uapi/sound/asound.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ struct snd_hwdep_dsp_image {
142142
* *
143143
*****************************************************************************/
144144

145-
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 17)
145+
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 18)
146146

147147
typedef unsigned long snd_pcm_uframes_t;
148148
typedef signed long snd_pcm_sframes_t;
@@ -334,7 +334,7 @@ union snd_pcm_sync_id {
334334
unsigned char id[16];
335335
unsigned short id16[8];
336336
unsigned int id32[4];
337-
};
337+
} __attribute__((deprecated));
338338

339339
struct snd_pcm_info {
340340
unsigned int device; /* RO/WR (control): device number */
@@ -348,7 +348,7 @@ struct snd_pcm_info {
348348
int dev_subclass; /* SNDRV_PCM_SUBCLASS_* */
349349
unsigned int subdevices_count;
350350
unsigned int subdevices_avail;
351-
union snd_pcm_sync_id sync; /* hardware synchronization ID */
351+
unsigned char pad1[16]; /* was: hardware synchronization ID */
352352
unsigned char reserved[64]; /* reserved for future... */
353353
};
354354

@@ -420,7 +420,8 @@ struct snd_pcm_hw_params {
420420
unsigned int rate_num; /* R: rate numerator */
421421
unsigned int rate_den; /* R: rate denominator */
422422
snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */
423-
unsigned char reserved[64]; /* reserved for future */
423+
unsigned char sync[16]; /* R: synchronization ID (perfect sync - one clock source) */
424+
unsigned char reserved[48]; /* reserved for future */
424425
};
425426

426427
enum {

sound/core/pcm_lib.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -525,10 +525,8 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream)
525525
{
526526
struct snd_pcm_runtime *runtime = substream->runtime;
527527

528-
runtime->sync.id32[0] = substream->pcm->card->number;
529-
runtime->sync.id32[1] = -1;
530-
runtime->sync.id32[2] = -1;
531-
runtime->sync.id32[3] = -1;
528+
*(__u32 *)runtime->sync = cpu_to_le32(substream->pcm->card->number);
529+
memset(runtime->sync + 4, 0xff, sizeof(runtime->sync) - 4);
532530
}
533531
EXPORT_SYMBOL(snd_pcm_set_sync);
534532

@@ -1810,6 +1808,25 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
18101808
return 0;
18111809
}
18121810

1811+
/**
1812+
* is sync id (clock id) empty?
1813+
*/
1814+
static inline bool pcm_sync_empty(const unsigned char *sync)
1815+
{
1816+
return sync[0] == 0 && sync[1] == 0 && sync[2] == 0 && sync[3] == 0 &&
1817+
sync[4] == 0 && sync[5] == 0 && sync[6] == 0 && sync[7] == 0;
1818+
}
1819+
1820+
static int snd_pcm_lib_ioctl_sync_id(struct snd_pcm_substream *substream,
1821+
void *arg)
1822+
{
1823+
struct snd_pcm_hw_params *params = arg;
1824+
1825+
if (pcm_sync_empty(params->sync))
1826+
memcpy(params->sync, substream->runtime->sync, sizeof(params->sync));
1827+
return 0;
1828+
}
1829+
18131830
/**
18141831
* snd_pcm_lib_ioctl - a generic PCM ioctl callback
18151832
* @substream: the pcm substream instance
@@ -1831,6 +1848,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
18311848
return snd_pcm_lib_ioctl_channel_info(substream, arg);
18321849
case SNDRV_PCM_IOCTL1_FIFO_SIZE:
18331850
return snd_pcm_lib_ioctl_fifo_size(substream, arg);
1851+
case SNDRV_PCM_IOCTL1_SYNC_ID:
1852+
return snd_pcm_lib_ioctl_sync_id(substream, arg);
18341853
}
18351854
return -ENXIO;
18361855
}

sound/core/pcm_native.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,12 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
533533
SNDRV_PCM_INFO_MMAP_VALID);
534534
}
535535

536+
err = snd_pcm_ops_ioctl(substream,
537+
SNDRV_PCM_IOCTL1_SYNC_ID,
538+
params);
539+
if (err < 0)
540+
return err;
541+
536542
return 0;
537543
}
538544

sound/pci/emu10k1/p16v.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,9 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea
174174
if (err < 0)
175175
return err;
176176

177-
runtime->sync.id32[0] = substream->pcm->card->number;
178-
runtime->sync.id32[1] = 'P';
179-
runtime->sync.id32[2] = 16;
180-
runtime->sync.id32[3] = 'V';
177+
*(__u32 *)runtime->sync = cpu_to_le32(substream->pcm->card->number);
178+
memset(runtime->sync + 4, 0, sizeof(runtime->sync) - 4);
179+
strncpy(runtime->sync + 4, "P16V", 4);
181180

182181
return 0;
183182
}

0 commit comments

Comments
 (0)