* [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups
@ 2023-05-16 9:36 Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 1/6] ALSA: emu10k1: straighten out FX send init Oswald Buddenhagen
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
Oswald Buddenhagen (6):
ALSA: emu10k1: straighten out FX send init
ALSA: emu10k1: cleanup envelope register init
ALSA: emu10k1: remove useless resets of stop-on-loop-end bits
ALSA: emu10k1: rewire {en,dis}abling interrupts for PCM playback
ALSA: emu10k1: skip needless setting of some voice registers
ALSA: emu10k1: factor out snd_emu10k1_compose_audigy_sendamounts()
Documentation/sound/cards/audigy-mixer.rst | 36 ++---
include/sound/emu10k1.h | 14 +-
sound/pci/emu10k1/emu10k1_main.c | 12 +-
sound/pci/emu10k1/emumixer.c | 51 +------
sound/pci/emu10k1/emupcm.c | 168 ++++++++++-----------
sound/pci/emu10k1/io.c | 63 +-------
6 files changed, 121 insertions(+), 223 deletions(-)
--
2.40.0.152.g15d061e6df
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] ALSA: emu10k1: straighten out FX send init
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
@ 2023-05-16 9:36 ` Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 2/6] ALSA: emu10k1: cleanup envelope register init Oswald Buddenhagen
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
The mixer structures were filled in two places: on driver init, and when
the devices are opened. The latter made the former pointless, so we
remove the former. This implies that mixer dumps may now return all
zeroes, which is OK, as restoring them is meaningless as well.
Things were even weirder for the (generally unused) secondary sends:
Some of the initialization loops were forgotten when support for Audigy
was added, thus creating the technically illegal state of multiple sends
being routed to the same FX accumulator (though it apparently doesn't
matter when the amount is zero).
The global multi-channel init used some rather bizarre values for the
secondary sends, and the init on open actually forgot to re-initialize
them. We now use a not really more useful, but simpler formula.
The direct register init was also bogus. This doesn't really matter, as
the value is overwritten when a voice comes into use, but still.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
Documentation/sound/cards/audigy-mixer.rst | 36 +++++++++---------
sound/pci/emu10k1/emu10k1_main.c | 2 +-
sound/pci/emu10k1/emumixer.c | 44 +---------------------
sound/pci/emu10k1/emupcm.c | 14 +++----
4 files changed, 26 insertions(+), 70 deletions(-)
diff --git a/Documentation/sound/cards/audigy-mixer.rst b/Documentation/sound/cards/audigy-mixer.rst
index e02dd890d089..ea66b50a2b03 100644
--- a/Documentation/sound/cards/audigy-mixer.rst
+++ b/Documentation/sound/cards/audigy-mixer.rst
@@ -240,30 +240,30 @@ name='EMU10K1 PCM Send Routing',index 0-31
This control specifies the destination - FX-bus accumulators. There are 24
values in this mapping:
-* 0 - mono, A destination (FX-bus 0-63), default 0
-* 1 - mono, B destination (FX-bus 0-63), default 1
-* 2 - mono, C destination (FX-bus 0-63), default 2
-* 3 - mono, D destination (FX-bus 0-63), default 3
-* 4 - mono, E destination (FX-bus 0-63), default 0
-* 5 - mono, F destination (FX-bus 0-63), default 0
-* 6 - mono, G destination (FX-bus 0-63), default 0
-* 7 - mono, H destination (FX-bus 0-63), default 0
-* 8 - left, A destination (FX-bus 0-63), default 0
-* 9 - left, B destination (FX-bus 0-63), default 1
+* 0 - mono, A destination (FX-bus 0-63), default 0
+* 1 - mono, B destination (FX-bus 0-63), default 1
+* 2 - mono, C destination (FX-bus 0-63), default 2
+* 3 - mono, D destination (FX-bus 0-63), default 3
+* 4 - mono, E destination (FX-bus 0-63), default 4
+* 5 - mono, F destination (FX-bus 0-63), default 5
+* 6 - mono, G destination (FX-bus 0-63), default 6
+* 7 - mono, H destination (FX-bus 0-63), default 7
+* 8 - left, A destination (FX-bus 0-63), default 0
+* 9 - left, B destination (FX-bus 0-63), default 1
* 10 - left, C destination (FX-bus 0-63), default 2
* 11 - left, D destination (FX-bus 0-63), default 3
-* 12 - left, E destination (FX-bus 0-63), default 0
-* 13 - left, F destination (FX-bus 0-63), default 0
-* 14 - left, G destination (FX-bus 0-63), default 0
-* 15 - left, H destination (FX-bus 0-63), default 0
+* 12 - left, E destination (FX-bus 0-63), default 4
+* 13 - left, F destination (FX-bus 0-63), default 5
+* 14 - left, G destination (FX-bus 0-63), default 6
+* 15 - left, H destination (FX-bus 0-63), default 7
* 16 - right, A destination (FX-bus 0-63), default 0
* 17 - right, B destination (FX-bus 0-63), default 1
* 18 - right, C destination (FX-bus 0-63), default 2
* 19 - right, D destination (FX-bus 0-63), default 3
-* 20 - right, E destination (FX-bus 0-63), default 0
-* 21 - right, F destination (FX-bus 0-63), default 0
-* 22 - right, G destination (FX-bus 0-63), default 0
-* 23 - right, H destination (FX-bus 0-63), default 0
+* 20 - right, E destination (FX-bus 0-63), default 4
+* 21 - right, F destination (FX-bus 0-63), default 5
+* 22 - right, G destination (FX-bus 0-63), default 6
+* 23 - right, H destination (FX-bus 0-63), default 7
Don't forget that it's illegal to assign a channel to the same FX-bus accumulator
more than once (it means 0=0 && 1=0 is an invalid combination).
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 068cb6624e36..5c8f38f20fcc 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -95,7 +95,7 @@ void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
snd_emu10k1_ptr_write(emu, A_CSFE, ch, 0);
snd_emu10k1_ptr_write(emu, A_CSHG, ch, 0);
snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
- snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
+ snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x07060504);
snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
}
}
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 9fa4bc845116..e067a4066cda 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1752,7 +1752,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
int pcm_device, int multi_device)
{
- int err, pcm;
+ int err;
struct snd_kcontrol *kctl;
struct snd_card *card = emu->card;
const char * const *c;
@@ -2016,48 +2016,6 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
if (err)
return err;
- /* initialize the routing and volume table for each pcm playback stream */
- for (pcm = 0; pcm < 32; pcm++) {
- struct snd_emu10k1_pcm_mixer *mix;
- int v;
-
- mix = &emu->pcm_mixer[pcm];
- mix->epcm = NULL;
-
- for (v = 0; v < 4; v++)
- mix->send_routing[0][v] =
- mix->send_routing[1][v] =
- mix->send_routing[2][v] = v;
-
- memset(&mix->send_volume, 0, sizeof(mix->send_volume));
- mix->send_volume[0][0] = mix->send_volume[0][1] =
- mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
-
- mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
- }
-
- /* initialize the routing and volume table for the multichannel playback stream */
- for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
- struct snd_emu10k1_pcm_mixer *mix;
- int v;
-
- mix = &emu->efx_pcm_mixer[pcm];
- mix->epcm = NULL;
-
- mix->send_routing[0][0] = pcm;
- mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
- for (v = 0; v < 2; v++)
- mix->send_routing[0][2+v] = 13+v;
- if (emu->audigy)
- for (v = 0; v < 4; v++)
- mix->send_routing[0][4+v] = 60+v;
-
- memset(&mix->send_volume, 0, sizeof(mix->send_volume));
- mix->send_volume[0][0] = 255;
-
- mix->attn[0] = 0xffff;
- }
-
if (!emu->card_capabilities->ecard && !emu->card_capabilities->emu_model) {
/* sb live! and audigy */
kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu);
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 6e6d3103ed90..c5ab0926d04f 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -283,11 +283,8 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
/* volume parameters */
if (extra) {
- memset(send_routing, 0, sizeof(send_routing));
- send_routing[0] = 0;
- send_routing[1] = 1;
- send_routing[2] = 2;
- send_routing[3] = 3;
+ for (int i = 0; i < 8; i++)
+ send_routing[i] = i;
memset(send_amount, 0, sizeof(send_amount));
} else {
/* mono, left, right (master voice = left) */
@@ -1031,7 +1028,7 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream)
struct snd_emu10k1_pcm *epcm;
struct snd_emu10k1_pcm_mixer *mix;
struct snd_pcm_runtime *runtime = substream->runtime;
- int i;
+ int i, j;
epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
if (epcm == NULL)
@@ -1046,7 +1043,8 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream)
for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
mix = &emu->efx_pcm_mixer[i];
- mix->send_routing[0][0] = i;
+ for (j = 0; j < 8; j++)
+ mix->send_routing[0][j] = i + j;
memset(&mix->send_volume, 0, sizeof(mix->send_volume));
mix->send_volume[0][0] = 255;
mix->attn[0] = 0x8000;
@@ -1093,7 +1091,7 @@ static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream)
return err;
}
mix = &emu->pcm_mixer[substream->number];
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 8; i++)
mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i;
memset(&mix->send_volume, 0, sizeof(mix->send_volume));
mix->send_volume[0][0] = mix->send_volume[0][1] =
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/6] ALSA: emu10k1: cleanup envelope register init
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 1/6] ALSA: emu10k1: straighten out FX send init Oswald Buddenhagen
@ 2023-05-16 9:36 ` Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 3/6] ALSA: emu10k1: remove useless resets of stop-on-loop-end bits Oswald Buddenhagen
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
We (rightfully) don't enable the envelope engine for PCM voices, so any
related setup is entirely pointless - the EMU8K documentation makes that
very clear, and the fact that the various open drivers all use different
values to no observable detriment pretty much confirms it.
The remaining initializations are regrouped for clarity.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
include/sound/emu10k1.h | 1 -
sound/pci/emu10k1/emu10k1_main.c | 10 +++---
sound/pci/emu10k1/emupcm.c | 42 ++++++----------------
sound/pci/emu10k1/io.c | 61 --------------------------------
4 files changed, 14 insertions(+), 100 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 7bcb1a2d779a..36687195c8f7 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1798,7 +1798,6 @@ void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait);
static inline unsigned int snd_emu10k1_wc(struct snd_emu10k1 *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data);
-unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
#ifdef CONFIG_PM_SLEEP
void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 5c8f38f20fcc..793ae8797172 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -58,7 +58,6 @@ MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
{
snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
- snd_emu10k1_ptr_write(emu, IP, ch, 0);
snd_emu10k1_ptr_write(emu, VTFT, ch, VTFT_FILTERTARGET_MASK);
snd_emu10k1_ptr_write(emu, CVCF, ch, CVCF_CURRENTFILTER_MASK);
snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
@@ -72,19 +71,18 @@ void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
snd_emu10k1_ptr_write(emu, Z2, ch, 0);
snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
- snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
+ // The rest is meaningless as long as DCYSUSV_CHANNELENABLE_MASK is zero
snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
+ snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
+ snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
+ snd_emu10k1_ptr_write(emu, IP, ch, 0);
snd_emu10k1_ptr_write(emu, IFATN, ch, IFATN_FILTERCUTOFF_MASK | IFATN_ATTENUATION_MASK);
snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
- snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
-
- /*** these are last so OFF prevents writing ***/
snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
- snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index c5ab0926d04f..d377669a8a94 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -348,24 +348,9 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0);
snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
- /* modulation envelope */
+ // Disable filter (in conjunction with CCCA_RESONANCE == 0)
snd_emu10k1_ptr_write(emu, VTFT, voice, VTFT_FILTERTARGET_MASK);
snd_emu10k1_ptr_write(emu, CVCF, voice, CVCF_CURRENTFILTER_MASK);
- snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
- snd_emu10k1_ptr_write(emu, DCYSUSM, voice, 0x007f);
- snd_emu10k1_ptr_write(emu, LFOVAL1, voice, 0x8000);
- snd_emu10k1_ptr_write(emu, LFOVAL2, voice, 0x8000);
- snd_emu10k1_ptr_write(emu, FMMOD, voice, 0);
- snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0);
- snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0);
- snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000);
- /* volume envelope */
- snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f);
- snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000);
- /* filter envelope */
- snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f);
- /* pitch envelope */
- snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0);
spin_unlock_irqrestore(&emu->reg_lock, flags);
}
@@ -600,51 +585,46 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
}
static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice,
- int master, int extra,
+ int master,
struct snd_emu10k1_pcm_mixer *mix)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
- unsigned int attn, vattn;
+ unsigned int vattn;
unsigned int voice, tmp;
if (evoice == NULL) /* skip second voice for mono */
return;
substream = evoice->epcm->substream;
runtime = substream->runtime;
voice = evoice->number;
- attn = extra ? 0 : 0x00ff;
tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
- snd_emu10k1_ptr_write(emu, IFATN, voice, attn);
snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | VTFT_FILTERTARGET_MASK);
snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | CVCF_CURRENTFILTER_MASK);
- snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f);
snd_emu10k1_voice_clear_loop_stop(emu, voice);
}
static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice, int master, int extra)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
- unsigned int voice, pitch, pitch_target;
+ unsigned int voice, pitch_target;
if (evoice == NULL) /* skip second voice for mono */
return;
substream = evoice->epcm->substream;
runtime = substream->runtime;
voice = evoice->number;
- pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8;
if (emu->card_capabilities->emu_model)
pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
else
pitch_target = emu10k1_calc_pitch_target(runtime->rate);
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
if (master || evoice->epcm->type == PLAYBACK_EFX)
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
- snd_emu10k1_ptr_write(emu, IP, voice, pitch);
if (extra)
snd_emu10k1_voice_intr_enable(emu, voice);
}
@@ -659,10 +639,8 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
snd_emu10k1_voice_intr_disable(emu, voice);
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
- snd_emu10k1_ptr_write(emu, IFATN, voice, 0xffff);
snd_emu10k1_ptr_write(emu, VTFT, voice, VTFT_FILTERTARGET_MASK);
snd_emu10k1_ptr_write(emu, CVCF, voice, CVCF_CURRENTFILTER_MASK);
- snd_emu10k1_ptr_write(emu, IP, voice, 0);
}
static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
@@ -707,9 +685,9 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
mix = &emu->pcm_mixer[substream->number];
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
- snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
+ snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, mix);
+ snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, mix);
+ snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, NULL);
snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0);
snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0);
snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
@@ -853,11 +831,11 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
fallthrough;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
- snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,
+ snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, NULL);
+ snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0,
&emu->efx_pcm_mixer[0]);
for (i = 1; i < NUM_EFX_PLAYBACK; i++)
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0,
+ snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0,
&emu->efx_pcm_mixer[i]);
snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);
snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 59b0f4d08c6b..f50943913a31 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -514,64 +514,3 @@ void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
outw(data, emu->port + AC97DATA);
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
-
-/*
- * convert rate to pitch
- */
-
-unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate)
-{
- static const u32 logMagTable[128] = {
- 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
- 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
- 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
- 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
- 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
- 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
- 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
- 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
- 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
- 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
- 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
- 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
- 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
- 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
- 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
- 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
- };
- static const char logSlopeTable[128] = {
- 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
- 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
- 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
- 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
- 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
- 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
- 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
- 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
- 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
- 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
- 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
- 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
- };
- int i;
-
- if (rate == 0)
- return 0; /* Bail out if no leading "1" */
- rate *= 11185; /* Scale 48000 to 0x20002380 */
- for (i = 31; i > 0; i--) {
- if (rate & 0x80000000) { /* Detect leading "1" */
- return (((unsigned int) (i - 15) << 20) +
- logMagTable[0x7f & (rate >> 24)] +
- (0x7f & (rate >> 17)) *
- logSlopeTable[0x7f & (rate >> 24)]);
- }
- rate <<= 1;
- }
-
- return 0; /* Should never reach this point */
-}
-
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/6] ALSA: emu10k1: remove useless resets of stop-on-loop-end bits
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 1/6] ALSA: emu10k1: straighten out FX send init Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 2/6] ALSA: emu10k1: cleanup envelope register init Oswald Buddenhagen
@ 2023-05-16 9:36 ` Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 4/6] ALSA: emu10k1: rewire {en,dis}abling interrupts for PCM playback Oswald Buddenhagen
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
We initialize them at card init and don't touch them later, so there is
no need to reset them again at voice start.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
include/sound/emu10k1.h | 2 ++
sound/pci/emu10k1/emupcm.c | 1 -
sound/pci/emu10k1/io.c | 2 ++
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 36687195c8f7..a5e935e16651 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1792,8 +1792,10 @@ void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
+#if 0
void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
+#endif
void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait);
static inline unsigned int snd_emu10k1_wc(struct snd_emu10k1 *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index d377669a8a94..2b6f5d2bbb3e 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -603,7 +603,6 @@ static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct s
vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | VTFT_FILTERTARGET_MASK);
snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | CVCF_CURRENTFILTER_MASK);
- snd_emu10k1_voice_clear_loop_stop(emu, voice);
}
static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice, int master, int extra)
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index f50943913a31..36fd6f7a0a2c 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -434,6 +434,7 @@ void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
+#if 0
void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
{
unsigned long flags;
@@ -471,6 +472,7 @@ void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voi
outl(sol, emu->port + DATA);
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
+#endif
void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
{
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/6] ALSA: emu10k1: rewire {en,dis}abling interrupts for PCM playback
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
` (2 preceding siblings ...)
2023-05-16 9:36 ` [PATCH 3/6] ALSA: emu10k1: remove useless resets of stop-on-loop-end bits Oswald Buddenhagen
@ 2023-05-16 9:36 ` Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 5/6] ALSA: emu10k1: skip needless setting of some voice registers Oswald Buddenhagen
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
We now enable ints even before triggering, and disable them only after
stopping - otherwise there is a race condition we may plausibly run into
when we pause/resume near the end of the buffer.
Updating the epcm->running flag is moved the same way, as it affects the
*_pointer() functions, which are called by the interrupt handler.
Also, factor these out to own functions, for clarity.
For multi-channel, the extra voice is now triggered after all regular
voices - we wouldn't want to receive an int before all channels have
passed the period boundary.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
sound/pci/emu10k1/emupcm.c | 45 ++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 16 deletions(-)
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 2b6f5d2bbb3e..7b0ab4e02cfd 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -605,7 +605,9 @@ static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct s
snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | CVCF_CURRENTFILTER_MASK);
}
-static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice, int master, int extra)
+static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_voice *evoice,
+ int master)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
@@ -624,24 +626,36 @@ static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct s
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
if (master || evoice->epcm->type == PLAYBACK_EFX)
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
- if (extra)
- snd_emu10k1_voice_intr_enable(emu, voice);
}
-static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice)
+static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_voice *evoice)
{
unsigned int voice;
if (evoice == NULL)
return;
voice = evoice->number;
- snd_emu10k1_voice_intr_disable(emu, voice);
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
snd_emu10k1_ptr_write(emu, VTFT, voice, VTFT_FILTERTARGET_MASK);
snd_emu10k1_ptr_write(emu, CVCF, voice, CVCF_CURRENTFILTER_MASK);
}
+static void snd_emu10k1_playback_set_running(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_pcm *epcm)
+{
+ epcm->running = 1;
+ snd_emu10k1_voice_intr_enable(emu, epcm->extra->number);
+}
+
+static void snd_emu10k1_playback_set_stopped(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_pcm *epcm)
+{
+ snd_emu10k1_voice_intr_disable(emu, epcm->extra->number);
+ epcm->running = 0;
+}
+
static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
struct snd_emu10k1_pcm *epcm,
struct snd_pcm_substream *substream,
@@ -687,18 +701,18 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, mix);
snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, mix);
snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, NULL);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
- epcm->running = 1;
+ snd_emu10k1_playback_set_running(emu, epcm);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
- epcm->running = 0;
snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]);
snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]);
snd_emu10k1_playback_stop_voice(emu, epcm->extra);
+ snd_emu10k1_playback_set_stopped(emu, epcm);
break;
default:
result = -EINVAL;
@@ -836,20 +850,19 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
for (i = 1; i < NUM_EFX_PLAYBACK; i++)
snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0,
&emu->efx_pcm_mixer[i]);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
- for (i = 1; i < NUM_EFX_PLAYBACK; i++)
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);
- epcm->running = 1;
+ snd_emu10k1_playback_set_running(emu, epcm);
+ for (i = 0; i < NUM_EFX_PLAYBACK; i++)
+ snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- epcm->running = 0;
for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
snd_emu10k1_playback_stop_voice(emu, epcm->voices[i]);
}
snd_emu10k1_playback_stop_voice(emu, epcm->extra);
+ snd_emu10k1_playback_set_stopped(emu, epcm);
break;
default:
result = -EINVAL;
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] ALSA: emu10k1: skip needless setting of some voice registers
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
` (3 preceding siblings ...)
2023-05-16 9:36 ` [PATCH 4/6] ALSA: emu10k1: rewire {en,dis}abling interrupts for PCM playback Oswald Buddenhagen
@ 2023-05-16 9:36 ` Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 6/6] ALSA: emu10k1: factor out snd_emu10k1_compose_audigy_sendamounts() Oswald Buddenhagen
2023-05-17 15:08 ` [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Takashi Iwai
6 siblings, 0 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
Many registers are meaningless for stereo slaves and the extra voices.
This patch cleans up these unnecessary register writes.
snd_emu10k1_playback_{trigger,stop}_voice() is not called for stereo
slaves any more.
snd_emu10k1_playback_prepare_voice() is renamed to
snd_emu10k1_playback_unmute_voice(), as this better reflects its
remaining function. It's not called for the extra voices any more.
Accordingly, snd_emu10k1_playback_mute_voice() is factored out from
snd_emu10k1_playback_stop_voice(), and is called selectively as well.
This doesn't add conditionals which would avoid initializing
sub-registers, as that wouldn't pull its weight.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
include/sound/emu10k1.h | 8 ++++
sound/pci/emu10k1/emupcm.c | 89 ++++++++++++++++++++------------------
2 files changed, 56 insertions(+), 41 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index a5e935e16651..5c1e5b123362 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -404,6 +404,14 @@ SUB_REG(HCFG, LOCKTANKCACHE, 0x00000004) /* 1 = Cancel bustmaster accesses to ta
// distortion), the modulation engine sets the target registers, towards
// which the current registers "swerve" gradually.
+// For the odd channel in a stereo pair, these registers are meaningless:
+// CPF_STEREO, CPF_CURRENTPITCH, PTRX_PITCHTARGET, CCR_CACHEINVALIDSIZE,
+// PSST_LOOPSTARTADDR, DSL_LOOPENDADDR, CCCA_CURRADDR
+// The somewhat non-obviously still meaningful ones are:
+// CPF_STOP, CPF_FRACADDRESS, CCR_READADDRESS (!),
+// CCCA_INTERPROM, CCCA_8BITSELECT (!)
+// (The envelope engine is ignored here, as stereo matters only for verbatim playback.)
+
#define CPF 0x00 /* Current pitch and fraction register */
SUB_REG(CPF, CURRENTPITCH, 0xffff0000) /* Current pitch (linear, 0x4000 == unity pitch shift) */
#define CPF_STEREO_MASK 0x00008000 /* 1 = Even channel interleave, odd channel locked */
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 7b0ab4e02cfd..4ade0ef2cd1b 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -301,12 +301,12 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
start_addr += ccis;
end_addr += ccis + emu->delay_pcm_irq;
}
- if (stereo && !extra) {
- snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
- snd_emu10k1_ptr_write(emu, CPF, (voice + 1), CPF_STEREO_MASK);
- } else {
- snd_emu10k1_ptr_write(emu, CPF, voice, 0);
- }
+ }
+ if (stereo && !extra) {
+ // Not really necessary for the slave, but it doesn't hurt
+ snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
+ } else {
+ snd_emu10k1_ptr_write(emu, CPF, voice, 0);
}
/* setup routing */
@@ -325,6 +325,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
snd_emu10k1_compose_send_routing(send_routing));
/* Assumption that PT is already 0 so no harm overwriting */
snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
+ // Stereo slaves don't need to have the addresses set, but it doesn't hurt
snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
snd_emu10k1_ptr_write(emu, PSST, voice,
(start_addr + (extra ? emu->delay_pcm_irq : 0)) |
@@ -554,8 +555,6 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
struct snd_pcm_runtime *runtime;
unsigned int voice, stereo, i, ccis, cra = 64, cs, sample;
- if (evoice == NULL)
- return;
runtime = evoice->epcm->substream->runtime;
voice = evoice->number;
stereo = (!extra && runtime->channels == 2);
@@ -575,71 +574,79 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
if (stereo) {
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
+ // The engine goes haywire if this one is out of sync
snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
}
/* fill cache */
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
if (stereo) {
snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
}
}
-static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice,
- int master,
- struct snd_emu10k1_pcm_mixer *mix)
+static void snd_emu10k1_playback_commit_volume(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_voice *evoice,
+ unsigned int vattn)
+{
+ snd_emu10k1_ptr_write(emu, VTFT, evoice->number, vattn | VTFT_FILTERTARGET_MASK);
+ snd_emu10k1_ptr_write(emu, CVCF, evoice->number, vattn | CVCF_CURRENTFILTER_MASK);
+}
+
+static void snd_emu10k1_playback_unmute_voice(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_voice *evoice,
+ bool master,
+ struct snd_emu10k1_pcm_mixer *mix)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
unsigned int vattn;
- unsigned int voice, tmp;
+ unsigned int tmp;
if (evoice == NULL) /* skip second voice for mono */
return;
substream = evoice->epcm->substream;
runtime = substream->runtime;
- voice = evoice->number;
tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
- vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
- snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | VTFT_FILTERTARGET_MASK);
- snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | CVCF_CURRENTFILTER_MASK);
+ vattn = mix->attn[tmp] << 16;
+ snd_emu10k1_playback_commit_volume(emu, evoice, vattn);
}
+static void snd_emu10k1_playback_mute_voice(struct snd_emu10k1 *emu,
+ struct snd_emu10k1_voice *evoice)
+{
+ if (evoice == NULL)
+ return;
+ snd_emu10k1_playback_commit_volume(emu, evoice, 0);
+}
+
static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu,
- struct snd_emu10k1_voice *evoice,
- int master)
+ struct snd_emu10k1_voice *evoice)
{
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
unsigned int voice, pitch_target;
- if (evoice == NULL) /* skip second voice for mono */
- return;
substream = evoice->epcm->substream;
runtime = substream->runtime;
voice = evoice->number;
if (emu->card_capabilities->emu_model)
pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
else
pitch_target = emu10k1_calc_pitch_target(runtime->rate);
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
- if (master || evoice->epcm->type == PLAYBACK_EFX)
- snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
+ snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
}
static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu,
struct snd_emu10k1_voice *evoice)
{
unsigned int voice;
- if (evoice == NULL)
- return;
voice = evoice->number;
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
- snd_emu10k1_ptr_write(emu, VTFT, voice, VTFT_FILTERTARGET_MASK);
- snd_emu10k1_ptr_write(emu, CVCF, voice, CVCF_CURRENTFILTER_MASK);
}
static void snd_emu10k1_playback_set_running(struct snd_emu10k1 *emu,
@@ -698,21 +705,20 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
mix = &emu->pcm_mixer[substream->number];
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, mix);
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, mix);
- snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, NULL);
+ 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_set_running(emu, epcm);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1);
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0]);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->extra);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]);
- snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]);
snd_emu10k1_playback_stop_voice(emu, epcm->extra);
snd_emu10k1_playback_set_stopped(emu, epcm);
+ snd_emu10k1_playback_mute_voice(emu, epcm->voices[0]);
+ snd_emu10k1_playback_mute_voice(emu, epcm->voices[1]);
break;
default:
result = -EINVAL;
@@ -844,25 +850,26 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
fallthrough;
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
- snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, NULL);
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0,
- &emu->efx_pcm_mixer[0]);
- for (i = 1; i < NUM_EFX_PLAYBACK; i++)
- snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0,
- &emu->efx_pcm_mixer[i]);
+ for (i = 0; i < NUM_EFX_PLAYBACK; i++)
+ snd_emu10k1_playback_unmute_voice(emu, epcm->voices[i], false,
+ &emu->efx_pcm_mixer[i]);
+
snd_emu10k1_playback_set_running(emu, epcm);
for (i = 0; i < NUM_EFX_PLAYBACK; i++)
- snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0);
- snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i]);
+ snd_emu10k1_playback_trigger_voice(emu, epcm->extra);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
snd_emu10k1_playback_stop_voice(emu, epcm->voices[i]);
}
snd_emu10k1_playback_stop_voice(emu, epcm->extra);
snd_emu10k1_playback_set_stopped(emu, epcm);
+
+ for (i = 0; i < NUM_EFX_PLAYBACK; i++)
+ snd_emu10k1_playback_mute_voice(emu, epcm->voices[i]);
break;
default:
result = -EINVAL;
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/6] ALSA: emu10k1: factor out snd_emu10k1_compose_audigy_sendamounts()
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
` (4 preceding siblings ...)
2023-05-16 9:36 ` [PATCH 5/6] ALSA: emu10k1: skip needless setting of some voice registers Oswald Buddenhagen
@ 2023-05-16 9:36 ` Oswald Buddenhagen
2023-05-17 15:08 ` [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Takashi Iwai
6 siblings, 0 replies; 8+ messages in thread
From: Oswald Buddenhagen @ 2023-05-16 9:36 UTC (permalink / raw)
To: alsa-devel; +Cc: Takashi Iwai, Jaroslav Kysela
Saves a bit of code duplication.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
---
include/sound/emu10k1.h | 3 +++
sound/pci/emu10k1/emumixer.c | 7 ++-----
sound/pci/emu10k1/emupcm.c | 5 +----
3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 5c1e5b123362..456af84735a8 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1501,6 +1501,9 @@ struct snd_emu10k1_pcm_mixer {
#define snd_emu10k1_compose_audigy_fxrt2(route) \
((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24))
+#define snd_emu10k1_compose_audigy_sendamounts(vol) \
+(((unsigned int)vol[4] << 24) | ((unsigned int)vol[5] << 16) | ((unsigned int)vol[6] << 8) | (unsigned int)vol[7])
+
struct snd_emu10k1_memblk {
struct snd_util_memblk mem;
/* private part */
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index e067a4066cda..1ebf161d410e 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1196,11 +1196,8 @@ static void update_emu10k1_send_volume(struct snd_emu10k1 *emu, int voice, unsig
snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
if (emu->audigy) {
- unsigned int val = ((unsigned int)volume[4] << 24) |
- ((unsigned int)volume[5] << 16) |
- ((unsigned int)volume[6] << 8) |
- (unsigned int)volume[7];
- snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
+ snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
+ snd_emu10k1_compose_audigy_sendamounts(volume));
}
}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 4ade0ef2cd1b..d669f93d8930 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -316,10 +316,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
snd_emu10k1_compose_audigy_fxrt2(send_routing));
snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
- ((unsigned int)send_amount[4] << 24) |
- ((unsigned int)send_amount[5] << 16) |
- ((unsigned int)send_amount[6] << 8) |
- (unsigned int)send_amount[7]);
+ snd_emu10k1_compose_audigy_sendamounts(send_amount));
} else
snd_emu10k1_ptr_write(emu, FXRT, voice,
snd_emu10k1_compose_send_routing(send_routing));
--
2.40.0.152.g15d061e6df
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
` (5 preceding siblings ...)
2023-05-16 9:36 ` [PATCH 6/6] ALSA: emu10k1: factor out snd_emu10k1_compose_audigy_sendamounts() Oswald Buddenhagen
@ 2023-05-17 15:08 ` Takashi Iwai
6 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2023-05-17 15:08 UTC (permalink / raw)
To: Oswald Buddenhagen; +Cc: alsa-devel, Jaroslav Kysela
On Tue, 16 May 2023 11:36:06 +0200,
Oswald Buddenhagen wrote:
>
>
> Oswald Buddenhagen (6):
> ALSA: emu10k1: straighten out FX send init
> ALSA: emu10k1: cleanup envelope register init
> ALSA: emu10k1: remove useless resets of stop-on-loop-end bits
> ALSA: emu10k1: rewire {en,dis}abling interrupts for PCM playback
> ALSA: emu10k1: skip needless setting of some voice registers
> ALSA: emu10k1: factor out snd_emu10k1_compose_audigy_sendamounts()
Applied all 6 patches now. Thanks.
Takashi
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-05-17 15:10 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-16 9:36 [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 1/6] ALSA: emu10k1: straighten out FX send init Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 2/6] ALSA: emu10k1: cleanup envelope register init Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 3/6] ALSA: emu10k1: remove useless resets of stop-on-loop-end bits Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 4/6] ALSA: emu10k1: rewire {en,dis}abling interrupts for PCM playback Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 5/6] ALSA: emu10k1: skip needless setting of some voice registers Oswald Buddenhagen
2023-05-16 9:36 ` [PATCH 6/6] ALSA: emu10k1: factor out snd_emu10k1_compose_audigy_sendamounts() Oswald Buddenhagen
2023-05-17 15:08 ` [PATCH 0/6] ALSA: emu10k1: assorted playback-related cleanups Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox