[PATCH 1/2] ALSA: emu10k1: enable bit-exact playback, part 3: pitch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxx>
---
 sound/pci/emu10k1/emupcm.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 1ca16f0ddbed..0b23ff8d9c3b 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -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,18 +627,16 @@ 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,
 					    struct snd_emu10k1_voice *evoice)
 {
 	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,
-- 
2.40.0.152.g15d061e6df




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux