Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
To: alsa-devel@lists.sourceforge.net
Subject: Re: [PATCH] remove emu10k1 pops/clicks at the   beginning and end of playback (fwd)
Date: Sat, 05 Mar 2005 09:29:26 +0100	[thread overview]
Message-ID: <d0bqba$esi$1@sea.gmane.org> (raw)
In-Reply-To: <1109960235.6442.9.camel@mindpipe>

[-- Attachment #1: Type: text/plain, Size: 2360 bytes --]

Lee Revell wrote:
> On Fri, 2005-03-04 at 22:30 +0100, Jindrich Makovicka wrote:
> 
>>> Lee Revell wrote:
>>
>>>> > It's not that the cciss register is buggy, it's just poorly understood.
>>
>>> 
>>> I don't mean the register alone, I mean the way ALSA sets it.
>>> 
>>
>>>> > See US patent 6138207 for the exact function of the cache control
>>>> > circuitry.  I can't get my brain around it, but maybe you can.
>>>> > 
>>>> > http://patft.uspto.gov/netacgi/nph-Parser?u=/netahtml/srchnum.htm&Sect1=PTO1&Sect2=HITOFF&p=1&r=1&l=50&f=G&d=PALL&s1=6138207.WKU.&OS=PN/6138207&RS=PN/6138207
>>
>>> 
>>> Thanks for the brain food, but today I am too tired to dive in  :) 
>>> 
>>
>>>> > Have you tried leaving the cciss setting alone, and just increasing cs
>>>> > to 16, which should cause it to silence the entire cache, not just the
>>>> > beginning?
>>
>>> 
>>> When I leave cciss alone, audio still heavily pops (16bit at the end, 
>>> 8bit at the beginning). When I change cciss the way OSS driver has it, 
>>> which I believe is correct, there is still a slight pop at the end for 
>>> both. After decreasing cciss a bit (4 samples), the pop at the end seems 
>>> to be gone. Unfortunately I cannot test it on other cards than my SB 1024.
>>> 
>>> My current patch is attached (applies to 2.6.11-mm1). I also moved cciss 
>>> setting to one place and made invalidate_cache honor the "extra" flag - 
>>> if extra is on, it does not invalidate the second channel.
>>> 
> 
> 
> OK, sounds good.
> 
> You will have to generate the patch against ALSA CVS.  This will require
> updating it to support the multichannel device, which is made up of 16
> mono channels, 16 bit, 48KHz only  (plus an extra voice for timing).
> Should be easy.
> 
> Then, repost it to alsa-devel.

So, as the the above patch appeared to be rather a proof of concept, 
here is the (hopefully) correct fix. It changes the following:

- CCIS setting, which was previously "upside down" is fixed and modified 
to supress the pop at the end

- CCIS values are now in one spot to allow tweaking

- invalidate_cache now purges complete cache for both channels.

Big thanks to Lee for his advices.

I don't see any reason the patch shouldn't apply to CVS, as the only 
change with wider impact is in invalidate_cache arguments, and all 
callers are updated.

Best regards,
-- 
Jindrich Makovicka

[-- Attachment #2: emupcm.c.diff2 --]
[-- Type: text/plain, Size: 3878 bytes --]

--- emupcm.c.orig	2005-03-02 09:40:37.000000000 +0100
+++ emupcm.c	2005-03-05 09:13:09.074485436 +0100
@@ -250,6 +250,22 @@
 		return CCCA_INTERPROM_2;
 }
 
+/*
+ * calculate cache invalidate size 
+ *
+ * stereo: channel is stereo
+ * w_16: using 16bit samples
+ *
+ * returns: cache invalidate size in samples
+ */
+static int inline emu10k1_ccis(int stereo, int w_16)
+{
+	if (w_16) {
+		return stereo ? 24 : 26;
+	} else {
+		return stereo ? 24*2 : 26*2;
+	}
+}
 
 static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu,
 				       int master, int extra,
@@ -304,9 +320,7 @@
 		memcpy(send_amount, &mix->send_volume[tmp][0], 8);
 	}
 
-	ccis = stereo ? 28 : 30;
-	if (w_16)
-		ccis *= 2;
+	ccis = emu10k1_ccis(stereo, w_16);
 	
 	if (master) {
 		evoice->epcm->ccca_start_addr = start_addr + ccis;
@@ -473,11 +487,14 @@
 
 	start_addr = epcm->start_addr;
 	end_addr = snd_pcm_lib_period_bytes(substream);
-	if (runtime->channels == 2)
+	if (runtime->channels == 2) {
+		start_addr >>= 1;
 		end_addr >>= 1;
+	}
 	end_addr += start_addr;
 	snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
 				   start_addr, end_addr);
+	start_addr = epcm->start_addr;
 	end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
 	snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
 				   start_addr, end_addr);
@@ -598,7 +615,7 @@
 	return 0;
 }
 
-static void snd_emu10k1_playback_invalidate_cache(emu10k1_t *emu, emu10k1_voice_t *evoice)
+static void snd_emu10k1_playback_invalidate_cache(emu10k1_t *emu, int extra, emu10k1_voice_t *evoice)
 {
 	snd_pcm_runtime_t *runtime;
 	unsigned int voice, i, ccis, cra = 64, cs, sample;
@@ -608,27 +625,26 @@
 	runtime = evoice->epcm->substream->runtime;
 	voice = evoice->number;
 	sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080;
-	if (runtime->channels == 2) {
-		ccis = 28;
-		cs = 4;
-	} else {
-		ccis = 30;
-		cs = 2;
-	}
-	if (sample == 0)	/* 16-bit */
-		ccis *= 2;
-	for (i = 0; i < cs; i++)
+	cs = 16;
+	ccis = emu10k1_ccis(!extra && runtime->channels == 2, sample == 0);
+	for (i = 0; i < cs; i++) {
 		snd_emu10k1_ptr_write(emu, CD0 + i, voice, sample);
-		
+		if (!extra && runtime->channels == 2) {
+			snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample);
+		}
+	}
 	// reset cache
 	snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0);
 	snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
-	if (runtime->channels == 2) {
+	if (!extra && runtime->channels == 2) {
 		snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
 		snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
 	}
 	// fill cache
 	snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
+	if (!extra && runtime->channels == 2) {
+		snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
+	}
 }
 
 static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra)
@@ -707,8 +723,8 @@
 	spin_lock(&emu->reg_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		snd_emu10k1_playback_invalidate_cache(emu, epcm->extra);	/* do we need this? */
-		snd_emu10k1_playback_invalidate_cache(emu, epcm->voices[0]);
+		snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra);	/* do we need this? */
+		snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0);
@@ -836,9 +852,9 @@
 	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, 0, epcm->voices[i]);
 		}
-		snd_emu10k1_playback_invalidate_cache(emu, epcm->extra);
+		snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra);
 
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:

  reply	other threads:[~2005-03-05  8:29 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-04  8:33 [PATCH] remove emu10k1 pops/clicks at the beginning and end of playback (fwd) Jaroslav Kysela
2005-03-04 18:17 ` Lee Revell
2005-03-05  8:29   ` Jindrich Makovicka [this message]
2005-03-05 11:05     ` James Courtier-Dutton
2005-03-05 11:46       ` Jindrich Makovicka
2005-03-05 14:37         ` James Courtier-Dutton
2005-03-05 14:46           ` Jindrich Makovicka
2005-03-05 19:08             ` Jindrich Makovicka
2005-03-05 20:25               ` Lee Revell
2005-03-05 21:17                 ` Jindrich Makovicka
2005-03-08 16:11               ` Takashi Iwai
2005-03-05 18:39         ` Lee Revell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='d0bqba$esi$1@sea.gmane.org' \
    --to=makovick@kmlinux.fjfi.cvut.cz \
    --cc=alsa-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox