Skip to content

Commit d712c58

Browse files
perexgtiwai
authored andcommitted
ALSA: pcm: optimize and clarify stream synchronization ID API
Optimize the memory usage in struct snd_pcm_runtime - use boolean value for the standard sync ID scheme. Introduce snd_pcm_set_sync_per_card function to build synchronization IDs. Signed-off-by: Jaroslav Kysela <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent f05c1ff commit d712c58

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

include/sound/pcm.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ struct snd_pcm_runtime {
402402
snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
403403
snd_pcm_uframes_t silence_filled; /* already filled part of silence area */
404404

405-
unsigned char sync[16]; /* hardware synchronization ID */
405+
bool std_sync_id; /* hardware synchronization - standard per card ID */
406406

407407
/* -- mmap -- */
408408
struct snd_pcm_mmap_status *status;
@@ -1156,7 +1156,18 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int
11561156

11571157
void snd_pcm_set_ops(struct snd_pcm * pcm, int direction,
11581158
const struct snd_pcm_ops *ops);
1159-
void snd_pcm_set_sync(struct snd_pcm_substream *substream);
1159+
void snd_pcm_set_sync_per_card(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params,
1160+
const unsigned char *id, unsigned int len);
1161+
/**
1162+
* snd_pcm_set_sync - set the PCM sync id
1163+
* @substream: the pcm substream
1164+
*
1165+
* Use the default PCM sync identifier for the specific card.
1166+
*/
1167+
static inline void snd_pcm_set_sync(struct snd_pcm_substream *substream)
1168+
{
1169+
substream->runtime->std_sync_id = true;
1170+
}
11601171
int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
11611172
unsigned int cmd, void *arg);
11621173
void snd_pcm_period_elapsed_under_stream_lock(struct snd_pcm_substream *substream);

sound/core/pcm_lib.c

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -516,19 +516,37 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction,
516516
EXPORT_SYMBOL(snd_pcm_set_ops);
517517

518518
/**
519-
* snd_pcm_set_sync - set the PCM sync id
519+
* snd_pcm_set_sync_per_card - set the PCM sync id with card number
520520
* @substream: the pcm substream
521+
* @params: modified hardware parameters
522+
* @id: identifier (max 12 bytes)
523+
* @len: identifier length (max 12 bytes)
521524
*
522-
* Sets the PCM sync identifier for the card.
525+
* Sets the PCM sync identifier for the card with zero padding.
526+
*
527+
* User space or any user should use this 16-byte identifier for a comparison only
528+
* to check if two IDs are similar or different. Special case is the identifier
529+
* containing only zeros. Interpretation for this combination is - empty (not set).
530+
* The contents of the identifier should not be interpreted in any other way.
531+
*
532+
* The synchronization ID must be unique per clock source (usually one sound card,
533+
* but multiple soundcard may use one PCM word clock source which means that they
534+
* are fully synchronized).
535+
*
536+
* This routine composes this ID using card number in first four bytes and
537+
* 12-byte additional ID. When other ID composition is used (e.g. for multiple
538+
* sound cards), make sure that the composition does not clash with this
539+
* composition scheme.
523540
*/
524-
void snd_pcm_set_sync(struct snd_pcm_substream *substream)
541+
void snd_pcm_set_sync_per_card(struct snd_pcm_substream *substream,
542+
struct snd_pcm_hw_params *params,
543+
const unsigned char *id, unsigned int len)
525544
{
526-
struct snd_pcm_runtime *runtime = substream->runtime;
527-
528-
*(__u32 *)runtime->sync = cpu_to_le32(substream->pcm->card->number);
529-
memset(runtime->sync + 4, 0xff, sizeof(runtime->sync) - 4);
545+
*(__u32 *)params->sync = cpu_to_le32(substream->pcm->card->number);
546+
len = max(12, len);
547+
strncpy(params->sync + 4, id, len);
548+
memset(params->sync + 4 + len, 0, 12 - len);
530549
}
531-
EXPORT_SYMBOL(snd_pcm_set_sync);
532550

533551
/*
534552
* Standard ioctl routine
@@ -1808,22 +1826,15 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
18081826
return 0;
18091827
}
18101828

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-
18201829
static int snd_pcm_lib_ioctl_sync_id(struct snd_pcm_substream *substream,
18211830
void *arg)
18221831
{
1823-
struct snd_pcm_hw_params *params = arg;
1832+
static const unsigned char id[12] = { 0xff, 0xff, 0xff, 0xff,
1833+
0xff, 0xff, 0xff, 0xff,
1834+
0xff, 0xff, 0xff, 0xff };
18241835

1825-
if (pcm_sync_empty(params->sync))
1826-
memcpy(params->sync, substream->runtime->sync, sizeof(params->sync));
1836+
if (substream->runtime->std_sync_id)
1837+
snd_pcm_set_sync_per_card(substream, arg, id, sizeof(id));
18271838
return 0;
18281839
}
18291840

sound/pci/emu10k1/p16v.c

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

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);
180-
181177
return 0;
182178
}
183179

@@ -225,6 +221,17 @@ static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream)
225221
return snd_p16v_pcm_open_capture_channel(substream, 0);
226222
}
227223

224+
static int snd_p16v_pcm_ioctl_playback(struct snd_pcm_substream *substream,
225+
unsigned int cmd, void *arg)
226+
{
227+
if (cmd == SNDRV_PCM_IOCTL1_SYNC_ID) {
228+
static const unsigned char id[4] = { 'P', '1', '6', 'V' };
229+
snd_pcm_set_sync_per_card(substream, arg, id, 4);
230+
return 0;
231+
}
232+
return snd_pcm_lib_ioctl(substream, cmd, arg);
233+
}
234+
228235
/* prepare playback callback */
229236
static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
230237
{
@@ -530,6 +537,7 @@ snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
530537
static const struct snd_pcm_ops snd_p16v_playback_front_ops = {
531538
.open = snd_p16v_pcm_open_playback_front,
532539
.close = snd_p16v_pcm_close_playback,
540+
.ioctl = snd_p16v_pcm_ioctl_playback,
533541
.prepare = snd_p16v_pcm_prepare_playback,
534542
.trigger = snd_p16v_pcm_trigger_playback,
535543
.pointer = snd_p16v_pcm_pointer_playback,

0 commit comments

Comments
 (0)