mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-13 15:19:26 -04:00
ALSA: emu10k1: enable bit-exact playback, part 3: pitch
CPF_CURRENTPITCH starts swerving towards PTRX_PITCHTARGET as soon as that is set. In practice this means that CPF_FRACADDRESS may acquire a non-zero value before we manage to force CPF_CURRENTPITCH to the final value, which would prevent bit-for-bit reproduction. To avoid that this state persists, we now reset CPF_FRACADDRESS when setting CPF_CURRENTPITCH, and to (mostly) avoid that it progresses too far in the first place (possibly even reaching CCCA_CURRADDR), we write PTRX and CPF in one critical section (though NMIs, etc. still make this unreliable). Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Link: https://lore.kernel.org/r/20230518140339.3722279-2-oswald.buddenhagen@gmx.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
committed by
Takashi Iwai
parent
5c2664cc09
commit
08e55ae996
@@ -601,6 +601,17 @@ static void snd_emu10k1_playback_mute_voice(struct snd_emu10k1 *emu,
|
||||
snd_emu10k1_playback_commit_volume(emu, evoice, 0);
|
||||
}
|
||||
|
||||
static void snd_emu10k1_playback_commit_pitch(struct snd_emu10k1 *emu,
|
||||
u32 voice, u32 pitch_target)
|
||||
{
|
||||
u32 ptrx = snd_emu10k1_ptr_read(emu, PTRX, voice);
|
||||
u32 cpf = snd_emu10k1_ptr_read(emu, CPF, voice);
|
||||
snd_emu10k1_ptr_write_multiple(emu, voice,
|
||||
PTRX, (ptrx & ~PTRX_PITCHTARGET_MASK) | pitch_target,
|
||||
CPF, (cpf & ~(CPF_CURRENTPITCH_MASK | CPF_FRACADDRESS_MASK)) | pitch_target,
|
||||
REGLIST_END);
|
||||
}
|
||||
|
||||
static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu,
|
||||
struct snd_emu10k1_voice *evoice)
|
||||
{
|
||||
@@ -616,8 +627,7 @@ static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu,
|
||||
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);
|
||||
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
|
||||
snd_emu10k1_playback_commit_pitch(emu, voice, pitch_target << 16);
|
||||
}
|
||||
|
||||
static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu,
|
||||
@@ -626,8 +636,7 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu,
|
||||
unsigned int voice;
|
||||
|
||||
voice = evoice->number;
|
||||
snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
|
||||
snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
|
||||
snd_emu10k1_playback_commit_pitch(emu, voice, 0);
|
||||
}
|
||||
|
||||
static void snd_emu10k1_playback_set_running(struct snd_emu10k1 *emu,
|
||||
|
||||
Reference in New Issue
Block a user