diff options
author | Oswald Buddenhagen | 2023-05-17 19:42:54 +0200 |
---|---|---|
committer | Takashi Iwai | 2023-05-18 07:30:34 +0200 |
commit | 9e72666b9ee1140b7ecc66abc30b1c694ed7a6a0 (patch) | |
tree | ecc0e55ec587f2608abce31bd969532f77bd42ce /sound/pci | |
parent | 5b1cd21f0f05757e724e18a599b391689f8565fc (diff) |
ALSA: emu10k1: improve API of low-level voice manipulation functions
Originally, there was a 1:1 relationship between the PCM streams' and
the low-level voices' parameters. The addition of multi-channel playback
partially invalidated that, but didn't introduce proper layering, so
things kept working only by virtue of the multi-channel device never
having two channels (yet). The upcoming addition of 32-bit playback
would complete upending the relationships.
So this patch detaches the low-level parameters from the high-level
ones: we pass pre-calculated bit width and stereo flags to the low-level
manipulation functions instead of calculating them in-place from the
stream parameters.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230517174256.3657060-7-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/emu10k1/emupcm.c | 50 |
1 files changed, 22 insertions, 28 deletions
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index feb575922738..bbe054be2448 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -239,6 +239,7 @@ static unsigned int emu10k1_select_interprom(unsigned int pitch_target) static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, int master, int extra, struct snd_emu10k1_voice *evoice, + bool w_16, bool stereo, unsigned int start_addr, unsigned int end_addr, struct snd_emu10k1_pcm_mixer *mix) @@ -246,15 +247,13 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream = evoice->epcm->substream; struct snd_pcm_runtime *runtime = substream->runtime; unsigned int silent_page, tmp; - int voice, stereo, w_16; + int voice; unsigned char send_amount[8]; unsigned char send_routing[8]; unsigned long flags; unsigned int pitch_target; voice = evoice->number; - stereo = runtime->channels == 2; - w_16 = snd_pcm_format_width(runtime->format) == 16; spin_lock_irqsave(&emu->reg_lock, flags); @@ -273,7 +272,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, if (master) { evoice->epcm->ccca_start_addr = start_addr + 64 - 3; } - if (stereo && !extra) { + if (stereo) { // Not really necessary for the slave, but it doesn't hurt snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK); } else { @@ -399,15 +398,15 @@ static int snd_emu10k1_playback_prepare(struct snd_pcm_substream *substream) start_addr = epcm->start_addr >> w_16; end_addr = start_addr + runtime->period_size; - snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, + snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, w_16, false, start_addr, end_addr, NULL); start_addr >>= stereo; end_addr = start_addr + runtime->buffer_size; - snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], + snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], w_16, stereo, start_addr, end_addr, &emu->pcm_mixer[substream->number]); if (epcm->voices[1]) - snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1], + snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1], w_16, true, start_addr, end_addr, &emu->pcm_mixer[substream->number]); return 0; @@ -426,17 +425,17 @@ static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream) channel_size = runtime->buffer_size; - snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, + snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, true, false, start_addr, start_addr + (channel_size / 2), NULL); /* only difference with the master voice is we use it for the pointer */ - snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], + snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], true, false, start_addr, start_addr + channel_size, &emu->efx_pcm_mixer[0]); start_addr += channel_size; for (i = 1; i < NUM_EFX_PLAYBACK; i++) { - snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i], + snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i], true, false, start_addr, start_addr + channel_size, &emu->efx_pcm_mixer[i]); start_addr += channel_size; @@ -513,16 +512,14 @@ static int snd_emu10k1_capture_prepare(struct snd_pcm_substream *substream) } static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, - struct snd_emu10k1_voice *evoice) + struct snd_emu10k1_voice *evoice, + bool w_16, bool stereo) { - struct snd_pcm_runtime *runtime; - unsigned voice, stereo, sample; + unsigned voice, sample; u32 ccr; - runtime = evoice->epcm->substream->runtime; voice = evoice->number; - stereo = (runtime->channels == 2); - sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080; + sample = w_16 ? 0 : 0x80808080; // We assume that the cache is resting at this point (i.e., // CCR_CACHEINVALIDSIZE is very small). @@ -552,20 +549,15 @@ static void snd_emu10k1_playback_commit_volume(struct snd_emu10k1 *emu, static void snd_emu10k1_playback_unmute_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice, - bool master, + bool stereo, bool master, struct snd_emu10k1_pcm_mixer *mix) { - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; unsigned int vattn; unsigned int tmp; if (evoice == NULL) /* skip second voice for mono */ return; - substream = evoice->epcm->substream; - runtime = substream->runtime; - - tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0; + tmp = stereo ? (master ? 1 : 2) : 0; vattn = mix->attn[tmp] << 16; snd_emu10k1_playback_commit_volume(emu, evoice, vattn); } @@ -628,6 +620,8 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_emu10k1_pcm *epcm = runtime->private_data; struct snd_emu10k1_pcm_mixer *mix; + bool w_16 = snd_pcm_format_width(runtime->format) == 16; + bool stereo = runtime->channels == 2; int result = 0; /* @@ -638,13 +632,13 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, spin_lock(&emu->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: - snd_emu10k1_playback_invalidate_cache(emu, epcm->voices[0]); + snd_emu10k1_playback_invalidate_cache(emu, epcm->voices[0], w_16, stereo); fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: mix = &emu->pcm_mixer[substream->number]; - snd_emu10k1_playback_unmute_voice(emu, epcm->voices[0], true, mix); - snd_emu10k1_playback_unmute_voice(emu, epcm->voices[1], false, mix); + snd_emu10k1_playback_unmute_voice(emu, epcm->voices[0], stereo, true, mix); + snd_emu10k1_playback_unmute_voice(emu, epcm->voices[1], stereo, false, mix); snd_emu10k1_playback_set_running(emu, epcm); snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0]); snd_emu10k1_playback_trigger_voice(emu, epcm->extra); @@ -782,13 +776,13 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: /* prepare voices */ for (i = 0; i < NUM_EFX_PLAYBACK; i++) { - snd_emu10k1_playback_invalidate_cache(emu, epcm->voices[i]); + snd_emu10k1_playback_invalidate_cache(emu, epcm->voices[i], true, false); } fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: for (i = 0; i < NUM_EFX_PLAYBACK; i++) - snd_emu10k1_playback_unmute_voice(emu, epcm->voices[i], false, + snd_emu10k1_playback_unmute_voice(emu, epcm->voices[i], false, true, &emu->efx_pcm_mixer[i]); snd_emu10k1_playback_set_running(emu, epcm); |