All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] emu10k1: add interval timer support
@ 2004-09-17  7:19 Lee Revell
  2004-09-17  8:59 ` Jaroslav Kysela
  0 siblings, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-09-17  7:19 UTC (permalink / raw)
  To: alsa-devel; +Cc: perex, tiwai

This patch adds the necessary functions to support the emu10k1's
interval timer.  The interval timer is the mechanism used by every other
known emu10k1 driver to generate the period interrupts for playback. 
These are ported from the OSS driver.

The card record, emu, maintains a linked list of timers, each containing
a pointer to a playback substream.  The open callback would install a
timer and the prepare callback would enable it; when the timer interrupt
fires, we walk the list of timers and call snd_pcm_period_elapsed for
any substreams whose timer has expired.  Supported intervals are 4-1024
sample periods.  The timer's tick rate is fixed at one sample period at
48KHZ, so you have to correct if using a different sample rate.

This patch does *not* change the behavior of the driver; it just adds
the necessary functions to install, uninstall, enable, disable, and set
the timer.  This is the first step to eliminating the extra voice; that
will be posted separately when it has been fully tested.

Lee

--

Signed-Off-By: Lee Revell <rlrevell@joe-job.com>

Index: alsa/alsa-kernel/include/emu10k1.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/include/emu10k1.h,v
retrieving revision 1.45
diff -u -r1.45 emu10k1.h
--- alsa/alsa-kernel/include/emu10k1.h	30 Jul 2004 12:57:24 -0000	1.45
+++ alsa-rlr/alsa-kernel/include/emu10k1.h	17 Sep 2004 06:47:36 -0000
@@ -779,6 +779,7 @@
 typedef struct _snd_emu10k1 emu10k1_t;
 typedef struct _snd_emu10k1_voice emu10k1_voice_t;
 typedef struct _snd_emu10k1_pcm emu10k1_pcm_t;
+typedef struct _snd_emu10k1_timer emu10k1_timer_t;
 
 typedef enum {
 	EMU10K1_PCM,
@@ -811,6 +812,7 @@
 	snd_pcm_substream_t *substream;
 	emu10k1_voice_t *voices[2];
 	emu10k1_voice_t *extra;
+	emu10k1_timer_t *timer;
 	unsigned short running;
 	unsigned short first_ptr;
 	snd_util_memblk_t *memblk;
@@ -1004,6 +1006,21 @@
 	emu10k1_midi_t midi2; /* for audigy */
 
 	unsigned int efx_voices_mask[2];
+
+	struct list_head	timers;
+	unsigned short		timer_delay;
+	spinlock_t		timer_lock;
+
+};
+
+struct _snd_emu10k1_timer 
+{
+	struct list_head list;
+	snd_pcm_substream_t *substream;
+	unsigned char state; 
+	unsigned short count;		/* current number of interrupts */
+	unsigned short count_max;	/* number of interrupts needed to call snd_pcm_period_elapsed */
+	unsigned short delay;           /* timer delay */
 };
 
 int snd_emu10k1_create(snd_card_t * card,
@@ -1077,6 +1095,18 @@
 int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
 					      snd_emu10k1_fx8010_irq_t *irq);
 
+/* interval timer */
+void snd_emu10k1_timer_install(emu10k1_t *emu, emu10k1_timer_t *timer, unsigned short delay);
+void snd_emu10k1_timer_uninstall(emu10k1_t *emu, emu10k1_timer_t *timer);
+void snd_emu10k1_timer_enable(emu10k1_t *emu, emu10k1_timer_t *timer);
+void snd_emu10k1_timer_disable(emu10k1_t *emu, emu10k1_timer_t *timer);
+void snd_emu10k1_timer_set(emu10k1_t *emu, unsigned short delay);
+
+#define TIMER_STOPPED 			0xffff 
+#define TIMER_STATE_INSTALLED 		0x01
+#define TIMER_STATE_ACTIVE		0x02
+#define TIMER_STATE_UNINSTALLED 	0x04
+
 #endif /* __KERNEL__ */
 
 /*
Index: alsa/alsa-kernel/pci/emu10k1/io.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/emu10k1/io.c,v
retrieving revision 1.7
diff -u -r1.7 io.c
--- alsa/alsa-kernel/pci/emu10k1/io.c	29 Jun 2004 16:10:33 -0000	1.7
+++ alsa-rlr/alsa-kernel/pci/emu10k1/io.c	17 Sep 2004 06:47:37 -0000
@@ -338,3 +338,153 @@
 
 	return (unsigned char) ans;
 }
+
+void emu10k1_timer_irqhandler(emu10k1_t *emu)
+{
+	emu10k1_timer_t *t;
+	struct list_head *entry;
+
+	spin_lock(&emu->timer_lock);
+
+	list_for_each(entry, &emu->timers) {
+		t = list_entry(entry, emu10k1_timer_t, list);
+
+		if (t->state & TIMER_STATE_ACTIVE) {
+			t->count++;
+			if (t->count == t->count_max) {
+				t->count = 0;
+				snd_pcm_period_elapsed(t->substream);
+			}
+		}
+	}
+
+	spin_unlock(&emu->timer_lock);
+
+	return;
+}
+
+void snd_emu10k1_timer_install(emu10k1_t *emu, emu10k1_timer_t *timer, unsigned short delay)
+{
+	emu10k1_timer_t *t;
+	struct list_head *entry;
+	unsigned long flags;
+
+	if (delay < 5)
+		delay = 5;
+
+	timer->delay = delay;
+	timer->state = TIMER_STATE_INSTALLED;
+
+	spin_lock_irqsave(&emu->timer_lock, flags);
+
+	timer->count_max = timer->delay / (emu->timer_delay < 1024 ? emu->timer_delay : 1024);
+	timer->count = timer->count_max - 1;
+
+	list_add(&timer->list, &emu->timers);
+
+	if (emu->timer_delay > delay) {
+		if (emu->timer_delay == TIMER_STOPPED)
+			snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
+
+		emu->timer_delay = delay;
+		delay = (delay < 1024 ? delay : 1024);
+
+		snd_emu10k1_timer_set(emu, delay);
+
+		list_for_each(entry, &emu->timers) {
+			t = list_entry(entry, emu10k1_timer_t, list);
+
+			t->count_max = t->delay / delay;
+			/* don't want to think much, just force scheduling 
+			   on the next interrupt */
+			t->count = t->count_max - 1;
+		}
+
+		printk("timer rate --> %u\n", delay);
+	}
+
+	spin_unlock_irqrestore(&emu->timer_lock, flags);
+
+	return;
+}
+
+void snd_emu10k1_timer_uninstall(emu10k1_t *emu, emu10k1_timer_t *timer)
+{
+	emu10k1_timer_t *t;
+	struct list_head *entry;
+	unsigned short delay = TIMER_STOPPED;
+	unsigned long flags;
+
+	if (timer->state == TIMER_STATE_UNINSTALLED)
+		return;
+
+	spin_lock_irqsave(&emu->timer_lock, flags);
+
+	list_del(&timer->list);
+
+	list_for_each(entry, &emu->timers) {
+		t = list_entry(entry, emu10k1_timer_t, list);
+
+		if (t->delay < delay)
+			delay = t->delay;
+	}
+
+	if (emu->timer_delay != delay) {
+		emu->timer_delay = delay;
+
+		if (delay == TIMER_STOPPED)
+			snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
+		else {
+			delay = (delay < 1024 ? delay : 1024);
+
+			snd_emu10k1_timer_set(emu, delay);
+
+			list_for_each(entry, &emu->timers) {
+				t = list_entry(entry, emu10k1_timer_t, list);
+
+				t->count_max = t->delay / delay;
+				t->count = t->count_max - 1;
+			}
+		}
+
+		printk("timer rate --> %u\n", delay);
+	}
+
+	spin_unlock_irqrestore(&emu->timer_lock, flags);
+
+	timer->state = TIMER_STATE_UNINSTALLED;
+
+	return;
+}
+
+void snd_emu10k1_timer_enable(emu10k1_t *emu, emu10k1_timer_t *timer)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&emu->timer_lock, flags);
+	timer->state |= TIMER_STATE_ACTIVE;
+	spin_unlock_irqrestore(&emu->timer_lock, flags);
+
+	return;
+}
+
+void snd_emu10k1_timer_disable(emu10k1_t *emu, emu10k1_timer_t *timer)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&emu->timer_lock, flags);
+	timer->state &= ~TIMER_STATE_ACTIVE;
+	spin_unlock_irqrestore(&emu->timer_lock, flags);
+
+	return;
+}
+
+void snd_emu10k1_timer_set(emu10k1_t *emu, unsigned short delay)
+{
+	/* Creative's driver locks and unlocks the card spinlock here; 
+	 * the ALSA driver does not have this lock. 
+	 * Callers already should have the timer_lock so this should 
+	 * not be needed */
+	outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
+}
+




-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-09-17  7:19 [PATCH] emu10k1: add interval timer support Lee Revell
@ 2004-09-17  8:59 ` Jaroslav Kysela
  2004-09-21 19:36   ` Lee Revell
  2004-11-03 19:43   ` [PATCH] emu10k1: add interval timer support Lee Revell
  0 siblings, 2 replies; 35+ messages in thread
From: Jaroslav Kysela @ 2004-09-17  8:59 UTC (permalink / raw)
  To: Lee Revell; +Cc: alsa-devel, tiwai

On Fri, 17 Sep 2004, Lee Revell wrote:

> This patch adds the necessary functions to support the emu10k1's
> interval timer.  The interval timer is the mechanism used by every other
> known emu10k1 driver to generate the period interrupts for playback. 
> These are ported from the OSS driver.

1) please, make snd_emu10k1_timer_set() function inlined
2) use atomic bitops for timer->state and make also enable/disable
   functions inlined
3) I don't like so much proposed scheduling as I stated in my previous 
   e-mails; you cannot guarantee the right period boundary acknowledge
   at all - there will be always some additional delay when more than one
   stream is activated
4) the more appropriate place for the card's timer is timer API
5) multichannel PCM should be created rather trying to do ugly things with
   timer

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-09-17  8:59 ` Jaroslav Kysela
@ 2004-09-21 19:36   ` Lee Revell
  2004-09-22 10:16     ` Takashi Iwai
  2004-11-03 19:43   ` [PATCH] emu10k1: add interval timer support Lee Revell
  1 sibling, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-09-21 19:36 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel, tiwai

On Fri, 2004-09-17 at 04:59, Jaroslav Kysela wrote:
> On Fri, 17 Sep 2004, Lee Revell wrote:
> 3) I don't like so much proposed scheduling as I stated in my previous 
>    e-mails; you cannot guarantee the right period boundary acknowledge
>    at all - there will be always some additional delay when more than one
>    stream is activated

OK, I think I see your point.  The channel loop interrupts give you
32/64 separate interrupt sources, where the timer interrupt is
monolithic, and won't work well with multiple streams using different
period sizes.

> 5) multichannel PCM should be created rather trying to do ugly things with
>    timer

This is my current project.  I almost have it working, but I have a few
questions.

I am using kX ASIO as a reference for how multichannel PCM should work. 
>From the application's point of view, this looks like 16 mono channels. 
In the mixer, for each of the 16 ASIO channels you have 4/8 drop down
boxes to set the FX send destinations and 4/8 sliders to set the send
amounts.  By default ASIO 1 goes to FXBus channel 0, 2 goes to FXBus 1,
etc.  Multiple applications can open the same ASIO channel and the
driver will allocate additional voices with the same send routing.

I think that the ALSA equivalent would be to have another device with
channels_min=channels_max=1, and 16 substreams for which the routing
would be controlled with the mixer; if multiple applications open the
same substream we would allocate another voice.  You would call
snd_pcm_period_elapsed for each of these streams in the handler for the
EFX capture interrupt.  All applications using this device must use the
same period size settings, as in the Windows driver, the only setting in
the ASIO control panel is the latency aka buffer size.

You would then use an .asoundrc plugin that would look like a 16 channel
PCM device, and would consist of 16 mono channels, hw:x,x,0 through
hw:x,x,15.

I am not sure of a few things.  Does it matter whether I use INTERLEAVED
or NONINTERLEAVED, since the device only supports mono streams?  Also,
since all capture and playback streams for this device will be updated
in the same interrupt handler, would it be best to use the linked
substreams feature of ALSA, or do this manually with list_for_each?

Lee 



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-21 19:36   ` Lee Revell
@ 2004-09-22 10:16     ` Takashi Iwai
  2004-09-22 10:17       ` Jaroslav Kysela
  2004-09-22 15:01       ` Lee Revell
  0 siblings, 2 replies; 35+ messages in thread
From: Takashi Iwai @ 2004-09-22 10:16 UTC (permalink / raw)
  To: Lee Revell; +Cc: Jaroslav Kysela, alsa-devel

At Tue, 21 Sep 2004 15:36:42 -0400,
Lee Revell wrote:
> 
> I am using kX ASIO as a reference for how multichannel PCM should work. 
> From the application's point of view, this looks like 16 mono channels. 
> In the mixer, for each of the 16 ASIO channels you have 4/8 drop down
> boxes to set the FX send destinations and 4/8 sliders to set the send
> amounts.  By default ASIO 1 goes to FXBus channel 0, 2 goes to FXBus 1,
> etc.  Multiple applications can open the same ASIO channel and the
> driver will allocate additional voices with the same send routing.
> 
> I think that the ALSA equivalent would be to have another device with
> channels_min=channels_max=1, and 16 substreams for which the routing
> would be controlled with the mixer; if multiple applications open the
> same substream we would allocate another voice.  You would call
> snd_pcm_period_elapsed for each of these streams in the handler for the
> EFX capture interrupt.  All applications using this device must use the
> same period size settings, as in the Windows driver, the only setting in
> the ASIO control panel is the latency aka buffer size.
>
> You would then use an .asoundrc plugin that would look like a 16 channel
> PCM device, and would consist of 16 mono channels, hw:x,x,0 through
> hw:x,x,15.

Maybe I didn't get your point, but why not simply provide a 16-channel
non-interleaved device?

> I am not sure of a few things.  Does it matter whether I use INTERLEAVED
> or NONINTERLEAVED, since the device only supports mono streams?

No, it shouldn't.

>  Also,
> since all capture and playback streams for this device will be updated
> in the same interrupt handler, would it be best to use the linked
> substreams feature of ALSA, or do this manually with list_for_each?

The interrupt handling of linked substreams are not in the linked
way.  The linked streams are provided for the synchronized start (and
stop).  The update must be done independently.  So, the correct
implementation is the latter, list_for_each in the irq handler,
regardless of the linked state.


Takashi


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-22 10:16     ` Takashi Iwai
@ 2004-09-22 10:17       ` Jaroslav Kysela
  2004-09-22 15:01       ` Lee Revell
  1 sibling, 0 replies; 35+ messages in thread
From: Jaroslav Kysela @ 2004-09-22 10:17 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Lee Revell, alsa-devel

On Wed, 22 Sep 2004, Takashi Iwai wrote:

> > You would then use an .asoundrc plugin that would look like a 16 channel
> > PCM device, and would consist of 16 mono channels, hw:x,x,0 through
> > hw:x,x,15.
> 
> Maybe I didn't get your point, but why not simply provide a 16-channel
> non-interleaved device?

Yes, I agree here with Takashi.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-22 10:16     ` Takashi Iwai
  2004-09-22 10:17       ` Jaroslav Kysela
@ 2004-09-22 15:01       ` Lee Revell
  2004-09-24 13:43         ` Takashi Iwai
  1 sibling, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-09-22 15:01 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Jaroslav Kysela, alsa-devel

On Wed, 2004-09-22 at 06:16, Takashi Iwai wrote:
> At Tue, 21 Sep 2004 15:36:42 -0400,
> Lee Revell wrote:
> > 
> > I am using kX ASIO as a reference for how multichannel PCM should work. 
> > From the application's point of view, this looks like 16 mono channels. 
> > In the mixer, for each of the 16 ASIO channels you have 4/8 drop down
> > boxes to set the FX send destinations and 4/8 sliders to set the send
> > amounts.  By default ASIO 1 goes to FXBus channel 0, 2 goes to FXBus 1,
> > etc.  Multiple applications can open the same ASIO channel and the
> > driver will allocate additional voices with the same send routing.
> > 
> > I think that the ALSA equivalent would be to have another device with
> > channels_min=channels_max=1, and 16 substreams for which the routing
> > would be controlled with the mixer; if multiple applications open the
> > same substream we would allocate another voice.  You would call
> > snd_pcm_period_elapsed for each of these streams in the handler for the
> > EFX capture interrupt.  All applications using this device must use the
> > same period size settings, as in the Windows driver, the only setting in
> > the ASIO control panel is the latency aka buffer size.
> >
> > You would then use an .asoundrc plugin that would look like a 16 channel
> > PCM device, and would consist of 16 mono channels, hw:x,x,0 through
> > hw:x,x,15.
> 
> Maybe I didn't get your point, but why not simply provide a 16-channel
> non-interleaved device?
> 

Several reasons.  With the kX driver, if I am using a ReWire host like
Ableton Live, and I want to use an app that is not ReWire capable, I
would have the app output to two extra ASIO channels, say 10 and 11, 
and Live can use these as inputs like any other physical input.  Live
would then output to ASIO 1/2 (front), ASIO 3/4 (rear), and ASIO 5/6
(headphones/prelisten).  It seems like the best way to do this in ALSA
is to have the driver support a bunch of mono channels and use alsalib
plugins to make multichannel devices out of these.

How would I open only channels 10 and 11 with one app and 1-6 with
another using a single 16 channel device?  

Also, it seemed like it would be easier to handle mmap with a bunch of
mono streams, but maybe I don't understand the mmap completely.  The OSS
driver for example does not support mmap for multichannel PCM.

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-22 15:01       ` Lee Revell
@ 2004-09-24 13:43         ` Takashi Iwai
  2004-09-24 13:56           ` Jaroslav Kysela
  0 siblings, 1 reply; 35+ messages in thread
From: Takashi Iwai @ 2004-09-24 13:43 UTC (permalink / raw)
  To: Lee Revell; +Cc: Jaroslav Kysela, alsa-devel

At Wed, 22 Sep 2004 11:01:11 -0400,
Lee Revell wrote:
> 
> On Wed, 2004-09-22 at 06:16, Takashi Iwai wrote:
> > At Tue, 21 Sep 2004 15:36:42 -0400,
> > Lee Revell wrote:
> > > 
> > > I am using kX ASIO as a reference for how multichannel PCM should work. 
> > > From the application's point of view, this looks like 16 mono channels. 
> > > In the mixer, for each of the 16 ASIO channels you have 4/8 drop down
> > > boxes to set the FX send destinations and 4/8 sliders to set the send
> > > amounts.  By default ASIO 1 goes to FXBus channel 0, 2 goes to FXBus 1,
> > > etc.  Multiple applications can open the same ASIO channel and the
> > > driver will allocate additional voices with the same send routing.
> > > 
> > > I think that the ALSA equivalent would be to have another device with
> > > channels_min=channels_max=1, and 16 substreams for which the routing
> > > would be controlled with the mixer; if multiple applications open the
> > > same substream we would allocate another voice.  You would call
> > > snd_pcm_period_elapsed for each of these streams in the handler for the
> > > EFX capture interrupt.  All applications using this device must use the
> > > same period size settings, as in the Windows driver, the only setting in
> > > the ASIO control panel is the latency aka buffer size.
> > >
> > > You would then use an .asoundrc plugin that would look like a 16 channel
> > > PCM device, and would consist of 16 mono channels, hw:x,x,0 through
> > > hw:x,x,15.
> > 
> > Maybe I didn't get your point, but why not simply provide a 16-channel
> > non-interleaved device?
> > 
> 
> Several reasons.  With the kX driver, if I am using a ReWire host like
> Ableton Live, and I want to use an app that is not ReWire capable, I
> would have the app output to two extra ASIO channels, say 10 and 11, 
> and Live can use these as inputs like any other physical input.  Live
> would then output to ASIO 1/2 (front), ASIO 3/4 (rear), and ASIO 5/6
> (headphones/prelisten).  It seems like the best way to do this in ALSA
> is to have the driver support a bunch of mono channels and use alsalib
> plugins to make multichannel devices out of these.
> 
> How would I open only channels 10 and 11 with one app and 1-6 with
> another using a single 16 channel device?  

It's doable to implement the multi-channel non-interleaved PCM with
multi open.  But even in this case, we provide eventually 16
substreams, so perhaps providing 16 mono substreams would be easier to
implement (at least for the kernel driver).

Regarding the efficiency (latency), there will be no difference
between the multi-channel and multi-substream implementations.
In the latter case, we can use linked substreams, as you already
mentioned.


> Also, it seemed like it would be easier to handle mmap with a bunch of
> mono streams, but maybe I don't understand the mmap completely.  The OSS
> driver for example does not support mmap for multichannel PCM.

This doesn't matter on ALSA.  The mmap of a multi-channel
non-interleaved substream is handled as well as a normal substream.
The snd_pcm_mmap_begin() and commit() hide the difference well.


Takashi


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-24 13:43         ` Takashi Iwai
@ 2004-09-24 13:56           ` Jaroslav Kysela
  2004-09-24 14:53             ` Paul Davis
  0 siblings, 1 reply; 35+ messages in thread
From: Jaroslav Kysela @ 2004-09-24 13:56 UTC (permalink / raw)
  To: Lee Revell; +Cc: alsa-devel

On Fri, 24 Sep 2004, Takashi Iwai wrote:

> > How would I open only channels 10 and 11 with one app and 1-6 with
> > another using a single 16 channel device?  
> 
> It's doable to implement the multi-channel non-interleaved PCM with
> multi open.  But even in this case, we provide eventually 16
> substreams, so perhaps providing 16 mono substreams would be easier to
> implement (at least for the kernel driver).
> 
> Regarding the efficiency (latency), there will be no difference
> between the multi-channel and multi-substream implementations.
> In the latter case, we can use linked substreams, as you already
> mentioned.

I don't understand much the requirement. If you want to use other ALSA 
(legacy) applications, you can reroute them to appropriate FX bus only.
The controls are already available.

The multichannel PCM should be best only for multichannel recording /
playback. You're trying to desing a new API which does not make much
sense.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-24 13:56           ` Jaroslav Kysela
@ 2004-09-24 14:53             ` Paul Davis
  2004-09-24 15:13               ` Takashi Iwai
  0 siblings, 1 reply; 35+ messages in thread
From: Paul Davis @ 2004-09-24 14:53 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: Lee Revell, alsa-devel

>On Fri, 24 Sep 2004, Takashi Iwai wrote:
>
>> > How would I open only channels 10 and 11 with one app and 1-6 with
>> > another using a single 16 channel device?  
>> 
>> It's doable to implement the multi-channel non-interleaved PCM with
>> multi open.  But even in this case, we provide eventually 16
>> substreams, so perhaps providing 16 mono substreams would be easier to
>> implement (at least for the kernel driver).
>> 
>> Regarding the efficiency (latency), there will be no difference
>> between the multi-channel and multi-substream implementations.
>> In the latter case, we can use linked substreams, as you already
>> mentioned.
>
>I don't understand much the requirement. If you want to use other ALSA 
>(legacy) applications, you can reroute them to appropriate FX bus only.
>The controls are already available.
>
>The multichannel PCM should be best only for multichannel recording /
>playback. You're trying to desing a new API which does not make much
>sense.

more to the point, perhaps, is that the very first implementation of
the RME Hammerfall (digi9652) driver that i did took lee's approach
and when we measured it, there was a very definite performance
hit. having to call the "elapsed" function for every mono stream added
measurable overhead. when we collapsed it back to a single
non-interleaved, 26 channel device, it was significantly more
efficient.

if the "multi" PCM device/plugin works this would be a far preferable
way to implement the multichannel PCM device on this card, IMHO.

--p


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-24 14:53             ` Paul Davis
@ 2004-09-24 15:13               ` Takashi Iwai
  2004-09-24 15:26                 ` Paul Davis
  2004-09-24 21:02                 ` emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support) Lee Revell
  0 siblings, 2 replies; 35+ messages in thread
From: Takashi Iwai @ 2004-09-24 15:13 UTC (permalink / raw)
  To: Paul Davis; +Cc: Jaroslav Kysela, Lee Revell, alsa-devel

At Fri, 24 Sep 2004 10:53:55 -0400,
Paul Davis wrote:
> 
> >On Fri, 24 Sep 2004, Takashi Iwai wrote:
> >
> >> > How would I open only channels 10 and 11 with one app and 1-6 with
> >> > another using a single 16 channel device?  
> >> 
> >> It's doable to implement the multi-channel non-interleaved PCM with
> >> multi open.  But even in this case, we provide eventually 16
> >> substreams, so perhaps providing 16 mono substreams would be easier to
> >> implement (at least for the kernel driver).
> >> 
> >> Regarding the efficiency (latency), there will be no difference
> >> between the multi-channel and multi-substream implementations.
> >> In the latter case, we can use linked substreams, as you already
> >> mentioned.
> >
> >I don't understand much the requirement. If you want to use other ALSA 
> >(legacy) applications, you can reroute them to appropriate FX bus only.
> >The controls are already available.
> >
> >The multichannel PCM should be best only for multichannel recording /
> >playback. You're trying to desing a new API which does not make much
> >sense.
> 
> more to the point, perhaps, is that the very first implementation of
> the RME Hammerfall (digi9652) driver that i did took lee's approach
> and when we measured it, there was a very definite performance
> hit. having to call the "elapsed" function for every mono stream added
> measurable overhead. when we collapsed it back to a single
> non-interleaved, 26 channel device, it was significantly more
> efficient.

It's a good point.  If you use the timer-style irq, the perfomance
decrease would be smaller, though, because you don't (can't) get irqs
per PCM stream.  However, the overhead must still exist.


Takashi


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-24 15:13               ` Takashi Iwai
@ 2004-09-24 15:26                 ` Paul Davis
  2004-09-24 15:33                   ` Takashi Iwai
  2004-09-24 21:02                 ` emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support) Lee Revell
  1 sibling, 1 reply; 35+ messages in thread
From: Paul Davis @ 2004-09-24 15:26 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Jaroslav Kysela, Lee Revell, alsa-devel

>> more to the point, perhaps, is that the very first implementation of
>> the RME Hammerfall (digi9652) driver that i did took lee's approach
>> and when we measured it, there was a very definite performance
>> hit. having to call the "elapsed" function for every mono stream added
>> measurable overhead. when we collapsed it back to a single
>> non-interleaved, 26 channel device, it was significantly more
>> efficient.
>
>It's a good point.  If you use the timer-style irq, the perfomance
>decrease would be smaller, though, because you don't (can't) get irqs
>per PCM stream.  However, the overhead must still exist.

it was the same with the digi9652 - one interrupt source per card
card, but the elapsed callback had to be made to each stream.

--p


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-09-24 15:26                 ` Paul Davis
@ 2004-09-24 15:33                   ` Takashi Iwai
  0 siblings, 0 replies; 35+ messages in thread
From: Takashi Iwai @ 2004-09-24 15:33 UTC (permalink / raw)
  To: Paul Davis; +Cc: Jaroslav Kysela, Lee Revell, alsa-devel

At Fri, 24 Sep 2004 11:26:15 -0400,
Paul Davis wrote:
> 
> >> more to the point, perhaps, is that the very first implementation of
> >> the RME Hammerfall (digi9652) driver that i did took lee's approach
> >> and when we measured it, there was a very definite performance
> >> hit. having to call the "elapsed" function for every mono stream added
> >> measurable overhead. when we collapsed it back to a single
> >> non-interleaved, 26 channel device, it was significantly more
> >> efficient.
> >
> >It's a good point.  If you use the timer-style irq, the perfomance
> >decrease would be smaller, though, because you don't (can't) get irqs
> >per PCM stream.  However, the overhead must still exist.
> 
> it was the same with the digi9652 - one interrupt source per card
> card, but the elapsed callback had to be made to each stream.

OK, then is it the overhead of kernel/user switches?
If we use multi mono streams, poll is called N times.  I can imagine
this would hit performance loss.

Other possibility is the overhead of the task done in
snd_pcm_period_elapsed().  But if this really hits, we have to
eliminate it.


Takashi


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-24 15:13               ` Takashi Iwai
  2004-09-24 15:26                 ` Paul Davis
@ 2004-09-24 21:02                 ` Lee Revell
  2004-09-24 22:32                   ` Paul Davis
                                     ` (2 more replies)
  1 sibling, 3 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-24 21:02 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Paul Davis, Jaroslav Kysela, alsa-devel

On Fri, 2004-09-24 at 11:13, Takashi Iwai wrote:
> At Fri, 24 Sep 2004 10:53:55 -0400,
> Paul Davis wrote:
> > 
> > >On Fri, 24 Sep 2004, Takashi Iwai wrote:
> > >
> > >> > How would I open only channels 10 and 11 with one app and 1-6 with
> > >> > another using a single 16 channel device?  
> > >> 
> > >> It's doable to implement the multi-channel non-interleaved PCM with
> > >> multi open.  But even in this case, we provide eventually 16
> > >> substreams, so perhaps providing 16 mono substreams would be easier to
> > >> implement (at least for the kernel driver).
> > >> 
> > >> Regarding the efficiency (latency), there will be no difference
> > >> between the multi-channel and multi-substream implementations.
> > >> In the latter case, we can use linked substreams, as you already
> > >> mentioned.
> > >
> > >I don't understand much the requirement. If you want to use other ALSA 
> > >(legacy) applications, you can reroute them to appropriate FX bus only.
> > >The controls are already available.
> > >
> > >The multichannel PCM should be best only for multichannel recording /
> > >playback. You're trying to desing a new API which does not make much
> > >sense.
> > 
> > more to the point, perhaps, is that the very first implementation of
> > the RME Hammerfall (digi9652) driver that i did took lee's approach
> > and when we measured it, there was a very definite performance
> > hit. having to call the "elapsed" function for every mono stream added
> > measurable overhead. when we collapsed it back to a single
> > non-interleaved, 26 channel device, it was significantly more
> > efficient.
> 
> It's a good point.  If you use the timer-style irq, the perfomance
> decrease would be smaller, though, because you don't (can't) get irqs
> per PCM stream.  However, the overhead must still exist.
> 

While certainly easier to implement in the driver, the problem with a
single 16 channel device is that it wastes voices.  In the example of a
non-ReWire compliant app (which is the same as working around a non-JACK
aware app), you would have to use 16 voices for each open, even if the
device will only use 2 of the channels.

The current driver does support something like this, via the FX send
routing controls for playback streams.  Really the only difference here
is that instead of using an extra voice for the timer like the current
driver, you would call the elapsed function in the EFX capture interrupt
handler.  I actually looked at the RME drivers and it would work in a
similar way; a single interrupt source for the full-duplex device.  The
timer interrupt will probably not be used at all; Jaroslav has convinced
me the extra voice is the best solution for regular PCM playback (system
sounds and whatnot). 

It is more efficient to use a single 16 channel non-interleaved device
if, as in the case of JACK, only one app will be using the device and it
will use all channels.  Individual mono streams become more efficient as
the channel count gets lower.

>From reading the changelogs of the kX drivers, and reading some posts
that the author made in the forums, it looks like they originally used a
single 16 channel device, then later moved to individual mono streams as
in my proposal.  For example their driver originally did not support
multiple open, because they probably just grabbed 16 voices at startup. 
Also with kX ASIO you can lower the CPU load by only opening as many
playback channels as you will use, because with multiple mono channels
the amount of work you do in the interrupt handler is proportional to
the number of channels.

Anyway I will probably start with whatever is easier to get working. 
This will actually not be a huge patch, and I certainly don't want to
design a new API.  I am just running through some more complex use cases
that I know work on Windows to verify I am on the right track.

Lee




-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-24 21:02                 ` emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support) Lee Revell
@ 2004-09-24 22:32                   ` Paul Davis
  2004-09-24 22:57                     ` Lee Revell
  2004-09-25  4:05                     ` Lee Revell
  2004-09-26  0:55                   ` Lee Revell
  2004-09-26 11:38                   ` Jaroslav Kysela
  2 siblings, 2 replies; 35+ messages in thread
From: Paul Davis @ 2004-09-24 22:32 UTC (permalink / raw)
  To: Lee Revell; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

>It is more efficient to use a single 16 channel non-interleaved device
>if, as in the case of JACK, only one app will be using the device and it
>will use all channels.  Individual mono streams become more efficient as
>the channel count gets lower.

this is a reasonable point. 

>Also with kX ASIO you can lower the CPU load by only opening as many
>playback channels as you will use, because with multiple mono channels
>the amount of work you do in the interrupt handler is proportional to
>the number of channels.

maybe so with kX ASIO, but this not true of ALSA. the work done by the
interrupt handler is proportional to the number of open streams, not
channels. a 26 channel device consumes the same number of cycles at
interrupt time as a single channel device.

the only thing that goes is required down with the channel count is
the bus bandwidth utilized. the CPU cycles used will depend on the
mixer configuration etc (i.e. do you have to silence the unused
channel buffers each time, or can you just mute them) ...

--p





-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-24 22:32                   ` Paul Davis
@ 2004-09-24 22:57                     ` Lee Revell
  2004-09-25  4:05                     ` Lee Revell
  1 sibling, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-24 22:57 UTC (permalink / raw)
  To: Paul Davis; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

On Fri, 2004-09-24 at 18:32, Paul Davis wrote:
> >Also with kX ASIO you can lower the CPU load by only opening as many
> >playback channels as you will use, because with multiple mono channels
> >the amount of work you do in the interrupt handler is proportional to
> >the number of channels.
> 
> maybe so with kX ASIO, but this not true of ALSA. the work done by the
> interrupt handler is proportional to the number of open streams, not
> channels. a 26 channel device consumes the same number of cycles at
> interrupt time as a single channel device.
> 
> the only thing that goes is required down with the channel count is
> the bus bandwidth utilized. the CPU cycles used will depend on the
> mixer configuration etc (i.e. do you have to silence the unused
> channel buffers each time, or can you just mute them) ...

OK, makes sense.  Maybe the kX driver behaves this way because of the
way ASIO calls the process callback from the interrupt handler.

Anyway, using a few more voices than necessary is not as much of an
issue.  The only important use of multiple open with this device is to
work around a non-JACK aware app by having it output to the FX bus.  It
seems that the single 16 channel device will be easier to implement, so
I am going to start with that, and the initial implementation will not
support multiple open for playback.

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-24 22:32                   ` Paul Davis
  2004-09-24 22:57                     ` Lee Revell
@ 2004-09-25  4:05                     ` Lee Revell
  1 sibling, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-25  4:05 UTC (permalink / raw)
  To: Paul Davis; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

On Fri, 2004-09-24 at 18:32, Paul Davis wrote:
> >It is more efficient to use a single 16 channel non-interleaved device
> >if, as in the case of JACK, only one app will be using the device and it
> >will use all channels.  Individual mono streams become more efficient as
> >the channel count gets lower.
> 
> this is a reasonable point. 
> 

OK, thanks everyone for your help.  I now have the basic device working.
At least, it compiles and I can open it...

I noticed the RME drivers use an interesting hack, of checking whether
the playback and capture device are open by the same PID.  My device
will require something similar, as it also requires the same period size
in both directions.  Would you recommend using the same method, or is
there a "better" way?  Seems like this will work fine for jack, which is
the targeted user anyway.

With ASIO, I think this problem is solved by some kind of system wide
hook.  If I use different ASIO apps, each will have a button in the
config that opens the system-wide ASIO control panel widget where I can
set the buffer size; changing it will change it for all apps.  Some
handle this better than others; some will hiccup and some will have to
have their audio engine restarted.

Maybe ALSA should implement a system-wide method to set properties like
this that apply to playback and capture devices.  Or maybe this is
better handled with a hardware specific app.

Lee









-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-24 21:02                 ` emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support) Lee Revell
  2004-09-24 22:32                   ` Paul Davis
@ 2004-09-26  0:55                   ` Lee Revell
  2004-09-26  2:51                     ` Lee Revell
  2004-09-26 11:38                   ` Jaroslav Kysela
  2 siblings, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-09-26  0:55 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Paul Davis, Jaroslav Kysela, alsa-devel

On Fri, 2004-09-24 at 17:02, Lee Revell wrote:
> Anyway I will probably start with whatever is easier to get working. 
> This will actually not be a huge patch, and I certainly don't want to
> design a new API.  I am just running through some more complex use cases
> that I know work on Windows to verify I am on the right track.

OK, hopefully I am on the right track.

Here's a normal stereo interleaved pcm being opened.  The L and R voices
have the same start and end addresses because it's interleaved, and the
extra voice is silent, it loops generating the period interrupts.  Here
16 periods per buffer are used.

init voice - master 1 extra 1 start_addr 0x1000 end_addr 0x2000
init voice - master 1 extra 0 start_addr 0x1000 end_addr 0x11000
init voice - master 0 extra 0 start_addr 0x1000 end_addr 0x11000

Here is the multichannel device being opened.  I split the buffer up
into 16 chunks, and allocate a voice for each:

pcm_channel_alloc: voices=16
in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x1000 end_addr 0x2000
init voice - master 1 extra 0 start_addr 0x2000 end_addr 0x3000
init voice - master 1 extra 0 start_addr 0x3000 end_addr 0x4000
Unable to handle kernel NULL pointer dereference at virtual address 00000010
 printing eip:

Looks good, until it Oops'es.  This is because currently the voice
allocator only handles one or two voices at a time, it blows up as soon
as I go to initialize the third voice.  I am working on this.

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26  0:55                   ` Lee Revell
@ 2004-09-26  2:51                     ` Lee Revell
  2004-09-26  3:10                       ` Lee Revell
  2004-09-26  3:15                       ` Paul Davis
  0 siblings, 2 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-26  2:51 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Paul Davis, Jaroslav Kysela, alsa-devel

On Sat, 2004-09-25 at 20:55, Lee Revell wrote:
> Looks good, until it Oops'es.  This is because currently the voice
> allocator only handles one or two voices at a time, it blows up as soon
> as I go to initialize the third voice.  I am working on this.

OK, I fixed the voice allocator to handle multichannel PCM.  Now it
looks like the prepare callback is being called over and over in a loop.

Here is the debug output from the prepare callback:

in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x1000 end_addr 0x2000
init voice - master 1 extra 0 start_addr 0x2000 end_addr 0x3000
init voice - master 1 extra 0 start_addr 0x3000 end_addr 0x4000
init voice - master 1 extra 0 start_addr 0x4000 end_addr 0x5000
init voice - master 1 extra 0 start_addr 0x5000 end_addr 0x6000
init voice - master 1 extra 0 start_addr 0x6000 end_addr 0x7000
init voice - master 1 extra 0 start_addr 0x7000 end_addr 0x8000
init voice - master 1 extra 0 start_addr 0x8000 end_addr 0x9000
init voice - master 1 extra 0 start_addr 0x9000 end_addr 0xa000
init voice - master 1 extra 0 start_addr 0xa000 end_addr 0xb000
init voice - master 1 extra 0 start_addr 0xb000 end_addr 0xc000
init voice - master 1 extra 0 start_addr 0xc000 end_addr 0xd000
init voice - master 1 extra 0 start_addr 0xd000 end_addr 0xe000
init voice - master 1 extra 0 start_addr 0xe000 end_addr 0xf000
init voice - master 1 extra 0 start_addr 0xf000 end_addr 0x10000
init voice - master 1 extra 0 start_addr 0x10000 end_addr 0x11000
in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x1000 end_addr 0x2000
init voice - master 1 extra 0 start_addr 0x2000 end_addr 0x3000

When I start jack, the above repeats endlessly.

Here is the prepare callback:

static int snd_emu10k1_efx_playback_prepare(snd_pcm_substream_t * substream)
{
        emu10k1_t *emu = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
        emu10k1_pcm_t *epcm = runtime->private_data;
        unsigned int start_addr, end_addr;

        start_addr = epcm->start_addr;
        end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
        printk("in snd_emu10k1_efx_playback_prepare - start_addr 0x%x end_addr 0x%x\n", start_addr,end_addr);

        /*
         * now we need to divide the buffer into 16 chunks and initialize
         * 16 voices to make the noninterleaved 16 channel stream
         */
        unsigned int channel_size;
        int i;
        channel_size = ( end_addr - start_addr ) / 16;
        for (i = 0; i < 16; i++) {
            snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[i],
                                   start_addr, start_addr+channel_size);
            start_addr += channel_size;
        }
   
        return 0;
}

I am still missing parts of the driver, like the interrupt handler.  But
it seems like the prepare callback should not loop this way.  Am I doing
something wrong?

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26  2:51                     ` Lee Revell
@ 2004-09-26  3:10                       ` Lee Revell
  2004-09-26  3:15                       ` Paul Davis
  1 sibling, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-26  3:10 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Paul Davis, Jaroslav Kysela, alsa-devel

On Sat, 2004-09-25 at 22:51, Lee Revell wrote:
> OK, I fixed the voice allocator to handle multichannel PCM.  Now it
> looks like the prepare callback is being called over and over in a loop.
> 
> I am still missing parts of the driver, like the interrupt handler.  But
> it seems like the prepare callback should not loop this way.  Am I doing
> something wrong?
> 

Never mind, I answered my own question - because I don't have an
interrupt handler yet jackd keeps restarting the stream when it gets
woken up by the capture interrupt and sees that nothing has happened on
the playback side.

So, jackd opens the 16 channel device correctly.  But speaker-test
doesn't seem to work.  I tried it like this:

rlrevell@mindpipe:~$ speaker-test -c 16 -D hw:0,3

speaker-test 1.0.5

Playback device is hw:0,3
Stream parameters are 48000Hz, S16_LE, 16 channels
Sine wave rate is 440.0000Hz
Access type not available for playback: Invalid argument
Setting of hwparams failed: Invalid argument

But, you can see in the logs that it does not even try to open the pcm. 
Is there a hardcoded limit of how many channels speaker-test supports?

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26  2:51                     ` Lee Revell
  2004-09-26  3:10                       ` Lee Revell
@ 2004-09-26  3:15                       ` Paul Davis
  2004-09-26  3:19                         ` Lee Revell
  2004-09-26  3:50                         ` Lee Revell
  1 sibling, 2 replies; 35+ messages in thread
From: Paul Davis @ 2004-09-26  3:15 UTC (permalink / raw)
  To: Lee Revell; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

>OK, I fixed the voice allocator to handle multichannel PCM.  Now it
>looks like the prepare callback is being called over and over in a loop.

   [ ... ]

>I am still missing parts of the driver, like the interrupt handler.  But
>it seems like the prepare callback should not loop this way.  Am I doing
>something wrong?

i would finish the driver before getting too deeply into this. the
interrupt handler is sorta-kinda important :)

jack has other ways of detecting timeouts, for example, and it may be
really calling the prepare callback many times.

--p


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26  3:15                       ` Paul Davis
@ 2004-09-26  3:19                         ` Lee Revell
  2004-09-26  3:50                         ` Lee Revell
  1 sibling, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-26  3:19 UTC (permalink / raw)
  To: Paul Davis; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

On Sat, 2004-09-25 at 23:15, Paul Davis wrote:
> >OK, I fixed the voice allocator to handle multichannel PCM.  Now it
> >looks like the prepare callback is being called over and over in a loop.
> 
>    [ ... ]
> 
> >I am still missing parts of the driver, like the interrupt handler.  But
> >it seems like the prepare callback should not loop this way.  Am I doing
> >something wrong?
> 
> i would finish the driver before getting too deeply into this. the
> interrupt handler is sorta-kinda important :)
> 

Yes, I just wanted to make sure I have the easy parts right, rather than
posting a huge patch and saying 'it doesn't work, anyone know why'. 
Anyway I think I have got it.

Thanks,

Lee 



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26  3:15                       ` Paul Davis
  2004-09-26  3:19                         ` Lee Revell
@ 2004-09-26  3:50                         ` Lee Revell
  2004-09-26  6:50                           ` Lee Revell
  1 sibling, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-09-26  3:50 UTC (permalink / raw)
  To: Paul Davis; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

On Sat, 2004-09-25 at 23:15, Paul Davis wrote:
> >OK, I fixed the voice allocator to handle multichannel PCM.  Now it
> >looks like the prepare callback is being called over and over in a loop.
> 
>    [ ... ]
> 
> >I am still missing parts of the driver, like the interrupt handler.  But
> >it seems like the prepare callback should not loop this way.  Am I doing
> >something wrong?
> 

The interrupt handler fortunately was a one liner.  All I have left is
the pointer callback and it should work.

I am really amazed at how much better ALSA is than OSS now.  Most of the
code in the OSS driver is not needed in the ALSA driver because the
middle layer is so powerful.

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26  3:50                         ` Lee Revell
@ 2004-09-26  6:50                           ` Lee Revell
  0 siblings, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-26  6:50 UTC (permalink / raw)
  To: Paul Davis; +Cc: Takashi Iwai, Jaroslav Kysela, alsa-devel

On Sat, 2004-09-25 at 23:50, Lee Revell wrote: 
> On Sat, 2004-09-25 at 23:15, Paul Davis wrote:
> > >OK, I fixed the voice allocator to handle multichannel PCM.  Now it
> > >looks like the prepare callback is being called over and over in a loop.
> > 
> >    [ ... ]
> > 
> > >I am still missing parts of the driver, like the interrupt handler.  But
> > >it seems like the prepare callback should not loop this way.  Am I doing
> > >something wrong?
> > 
> 
> The interrupt handler fortunately was a one liner.  All I have left is
> the pointer callback and it should work.

OK, I have the basic driver working, but I think I am doing something
wrong somewhere.  Jack can open the device but the watchdog thread times
it out, and it looks like the prepare callback is being called over and
over.  However the hardware pointer looks correct:

ptr = 0x84c, ccca_start_addr = 0x803c
ptr = 0x10, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
ptr = 0xc2f, ccca_start_addr = 0x803c
ptr = 0x3f3, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x800 end_addr 0x1000
init voice - master 1 extra 0 start_addr 0x1000 end_addr 0x1800
init voice - master 1 extra 0 start_addr 0x1800 end_addr 0x2000
init voice - master 1 extra 0 start_addr 0x2000 end_addr 0x2800
init voice - master 1 extra 0 start_addr 0x2800 end_addr 0x3000
init voice - master 1 extra 0 start_addr 0x3000 end_addr 0x3800
init voice - master 1 extra 0 start_addr 0x3800 end_addr 0x4000
init voice - master 1 extra 0 start_addr 0x4000 end_addr 0x4800
init voice - master 1 extra 0 start_addr 0x4800 end_addr 0x5000
init voice - master 1 extra 0 start_addr 0x5000 end_addr 0x5800
init voice - master 1 extra 0 start_addr 0x5800 end_addr 0x6000
init voice - master 1 extra 0 start_addr 0x6000 end_addr 0x6800
init voice - master 1 extra 0 start_addr 0x6800 end_addr 0x7000
init voice - master 1 extra 0 start_addr 0x7000 end_addr 0x7800
init voice - master 1 extra 0 start_addr 0x7800 end_addr 0x8000
init voice - master 1 extra 0 start_addr 0x8000 end_addr 0x8800
ptr = 0x84d, ccca_start_addr = 0x803c
ptr = 0x11, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
ptr = 0xc2f, ccca_start_addr = 0x803c
ptr = 0x3f3, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x800 end_addr 0x1000

...

init voice - master 1 extra 0 start_addr 0x8000 end_addr 0x8800
ptr = 0x84d, ccca_start_addr = 0x803c
ptr = 0x11, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
ptr = 0xc2f, ccca_start_addr = 0x803c
ptr = 0x3f3, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x800 end_addr 0x1000

...

init voice - master 1 extra 0 start_addr 0x8000 end_addr 0x8800
ptr = 0x84c, ccca_start_addr = 0x803c
ptr = 0x10, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
ptr = 0xc2f, ccca_start_addr = 0x803c
ptr = 0x3f3, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
in snd_emu10k1_efx_playback_prepare - start_addr 0x1000 end_addr 0x11000
init voice - master 1 extra 0 start_addr 0x800 end_addr 0x1000

...

init voice - master 1 extra 0 start_addr 0x8000 end_addr 0x8800
ptr = 0x84e, ccca_start_addr = 0x803c
ptr = 0x12, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream
ptr = 0xc2c, ccca_start_addr = 0x803c
ptr = 0x3f0, buffer_size = 0x800, period_size = 0x400
in capture efx irq handler, updating playback stream

The jitter is about the same as with the extra voice method, 0-3
samples.  However it looks like with every other interrupt it resets the
stream.

Do I need to post the code to debug this further?

Lee




-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-24 21:02                 ` emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support) Lee Revell
  2004-09-24 22:32                   ` Paul Davis
  2004-09-26  0:55                   ` Lee Revell
@ 2004-09-26 11:38                   ` Jaroslav Kysela
  2004-09-27  0:40                     ` Lee Revell
  2 siblings, 1 reply; 35+ messages in thread
From: Jaroslav Kysela @ 2004-09-26 11:38 UTC (permalink / raw)
  To: Lee Revell; +Cc: alsa-devel

On Fri, 24 Sep 2004, Lee Revell wrote:

> While certainly easier to implement in the driver, the problem with a
> single 16 channel device is that it wastes voices.  In the example of a
> non-ReWire compliant app (which is the same as working around a non-JACK
> aware app), you would have to use 16 voices for each open, even if the
> device will only use 2 of the channels.

No, read carefully my messages:

- legacy applications will use standard device
- multichannel applications will use one (or more) multichannel device

Then you need an application like ReWire which will touch / modify the 
universal controls to reroute channels from bloth multichannel and legacy 
application to appropriate FX bus.

Everybody will be happy with minimal count of extended voices.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-26 11:38                   ` Jaroslav Kysela
@ 2004-09-27  0:40                     ` Lee Revell
  2004-09-27  6:48                       ` Jaroslav Kysela
  0 siblings, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-09-27  0:40 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel

On Sun, 2004-09-26 at 07:38, Jaroslav Kysela wrote:
> On Fri, 24 Sep 2004, Lee Revell wrote:
> 
> > While certainly easier to implement in the driver, the problem with a
> > single 16 channel device is that it wastes voices.  In the example of a
> > non-ReWire compliant app (which is the same as working around a non-JACK
> > aware app), you would have to use 16 voices for each open, even if the
> > device will only use 2 of the channels.
> 
> No, read carefully my messages:
> 
> - legacy applications will use standard device
> - multichannel applications will use one (or more) multichannel device
> 

I think I understand you.  This is how I have written the driver.  I'll
post a patch as soon as the code is cleaned up.


> Then you need an application like ReWire which will touch / modify the 
> universal controls to reroute channels from bloth multichannel and legacy 
> application to appropriate FX bus.

Yes, the mixer support is an issue I have not addressed yet.  It will
also require ld10k1 and some additional DSP code; since the EFX device
captures the outputs and not the FX buses you need to connect FX buses
(or physical inputs) to the outputs that are selected with the "EFX
voices mask" control.

> 
> Everybody will be happy with minimal count of extended voices.
>

Yes, I agree.  Right now I have the first 16 voices reserved for the
multichannel device.  For the default playback device voice allocation
starts at 16. 

Lee



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-27  0:40                     ` Lee Revell
@ 2004-09-27  6:48                       ` Jaroslav Kysela
  2004-09-27 14:35                         ` Lee Revell
  0 siblings, 1 reply; 35+ messages in thread
From: Jaroslav Kysela @ 2004-09-27  6:48 UTC (permalink / raw)
  To: Lee Revell; +Cc: alsa-devel

On Sun, 26 Sep 2004, Lee Revell wrote:

> Yes, I agree.  Right now I have the first 16 voices reserved for the
> multichannel device.  For the default playback device voice allocation
> starts at 16. 

I would prefer dynamic voice allocations.

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs


-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support)
  2004-09-27  6:48                       ` Jaroslav Kysela
@ 2004-09-27 14:35                         ` Lee Revell
  0 siblings, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-09-27 14:35 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel

On Mon, 2004-09-27 at 02:48, Jaroslav Kysela wrote:
> On Sun, 26 Sep 2004, Lee Revell wrote:
> 
> > Yes, I agree.  Right now I have the first 16 voices reserved for the
> > multichannel device.  For the default playback device voice allocation
> > starts at 16. 
> 
> I would prefer dynamic voice allocations.
> 

So would I.  This setup is just for testing.  It will allocate voices
dynamically when it's finished.

Lee 



-------------------------------------------------------
This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
Project Admins to receive an Apple iPod Mini FREE for your judgement on
who ports your project to Linux PPC the best. Sponsored by IBM.
Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-09-17  8:59 ` Jaroslav Kysela
  2004-09-21 19:36   ` Lee Revell
@ 2004-11-03 19:43   ` Lee Revell
  2004-11-03 21:24     ` Lee Revell
  2004-11-04 17:05     ` Jaroslav Kysela
  1 sibling, 2 replies; 35+ messages in thread
From: Lee Revell @ 2004-11-03 19:43 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel, tiwai

On Fri, 2004-09-17 at 10:59 +0200, Jaroslav Kysela wrote:
> On Fri, 17 Sep 2004, Lee Revell wrote:
> 
> > This patch adds the necessary functions to support the emu10k1's
> > interval timer.  The interval timer is the mechanism used by every other
> > known emu10k1 driver to generate the period interrupts for playback. 
> > These are ported from the OSS driver.
> 
> 1) please, make snd_emu10k1_timer_set() function inlined
> 2) use atomic bitops for timer->state and make also enable/disable
>    functions inlined
> 3) I don't like so much proposed scheduling as I stated in my previous 
>    e-mails; you cannot guarantee the right period boundary acknowledge
>    at all - there will be always some additional delay when more than one
>    stream is activated
> 4) the more appropriate place for the card's timer is timer API
> 5) multichannel PCM should be created rather trying to do ugly things with
>    timer

OK I converted this code to use the ALSA timer API.  This seems to work
fine, I can access the timer from userspace.  However there does not
seem to be an existing example of a driver that uses the ALSA timer API
internally; all the drivers that use the interval timer internally for
PCM period interrupts have open coded timer handling.  AFAICT the ALSA
timer API should be OK for this purpose as well.  Is this correct?

I am going to use the interval timer for multichannel PCM playback.
This works by allocating 16 voices, setting loop stop on all of them,
then setting the timer.  In the first timer interrupt we clear loop stop
on all the voices with one PCI write, then re-arm the timer, and set the
PCM running; we now have 16 voices in perfect sync.  Subsequent timer
interrupts just call snd_pcm_period_elapsed.

The above scheme could also work with an extra voice for timing but
would be uglier.  Since the multichannel device does not have to support
multiple open, and only 48KHZ playback, the timer seems to be a much
cleaner solution.  Regular PCM playback will continue to use the extra
voice.

-- 
Lee Revell <rlrevell@joe-job.com>



-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH] emu10k1: add interval timer support
  2004-11-03 19:43   ` [PATCH] emu10k1: add interval timer support Lee Revell
@ 2004-11-03 21:24     ` Lee Revell
  2004-11-03 23:08       ` Lee Revell
  2004-11-09 14:24       ` Takashi Iwai
  2004-11-04 17:05     ` Jaroslav Kysela
  1 sibling, 2 replies; 35+ messages in thread
From: Lee Revell @ 2004-11-03 21:24 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel, tiwai

On Wed, 2004-11-03 at 14:43 -0500, Lee Revell wrote:
> OK I converted this code to use the ALSA timer API.

Here is the patch against ALSA CVS.  I tested it with the ALSA from
kernel 2.6.9-rc3-mm3 because CVS does not build currently.

diff -Nru alsa-orig/alsa-kernel/pci/emu10k1/emu10k1.c alsa/alsa-kernel/pci/emu10k1/emu10k1.c
--- alsa-orig/alsa-kernel/pci/emu10k1/emu10k1.c	2004-10-23 12:10:27.000000000 -0400
+++ alsa/alsa-kernel/pci/emu10k1/emu10k1.c	2004-11-03 13:21:06.000000000 -0500
@@ -124,6 +124,12 @@
 		snd_card_free(card);
 		return err;
 	}
+	
+	if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
 	if (emu->audigy) {
 		if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
 			snd_card_free(card);
diff -Nru alsa-orig/alsa-kernel/pci/emu10k1/irq.c alsa/alsa-kernel/pci/emu10k1/irq.c
--- alsa-orig/alsa-kernel/pci/emu10k1/irq.c	2004-06-29 12:10:33.000000000 -0400
+++ alsa/alsa-kernel/pci/emu10k1/irq.c	2004-11-03 13:22:02.000000000 -0500
@@ -112,8 +112,8 @@
 			status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
 		}
 		if (status & IPR_INTERVALTIMER) {
-			if (emu->timer_interrupt)
-				emu->timer_interrupt(emu);
+			if (emu->timer)
+				snd_timer_interrupt(emu->timer, emu->timer->sticks);
 			else
 				snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
 			status &= ~IPR_INTERVALTIMER;
diff -Nru alsa-orig/alsa-kernel/pci/emu10k1/timer.c alsa/alsa-kernel/pci/emu10k1/timer.c
--- alsa-orig/alsa-kernel/pci/emu10k1/timer.c	1969-12-31 19:00:00.000000000 -0500
+++ alsa/alsa-kernel/pci/emu10k1/timer.c	2004-11-03 16:20:54.000000000 -0500
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (c) by Lee Revell <rlrevell@joe-job.com>
+ *  
+ *  Routines for control of EMU10K1 chips
+ *
+ *  Copied from similar code by Clemens Ladisch in the ymfpci driver
+ * 
+ *  BUGS:
+ *    --
+ *
+ *  TODO:
+ *    --
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <sound/driver.h>
+#include <linux/time.h>
+#include <sound/core.h>
+#include <sound/emu10k1.h>
+
+static int snd_emu10k1_timer_start(snd_timer_t *timer)
+{
+	emu10k1_t *emu;
+	unsigned long flags;
+	unsigned int delay;
+
+	emu = snd_timer_chip(timer);
+	delay = timer->sticks - 1;
+	if (delay < 5 ) /* minimum time is 5 ticks */
+		delay = 5;
+	spin_lock_irqsave(&emu->reg_lock, flags);
+	snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
+	outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
+	spin_unlock_irqrestore(&emu->reg_lock, flags);
+	return 0;
+}
+
+static int snd_emu10k1_timer_stop(snd_timer_t *timer)
+{
+	emu10k1_t *emu;
+	unsigned long flags;
+
+	emu = snd_timer_chip(timer);
+	spin_lock_irqsave(&emu->reg_lock, flags);
+	snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
+	spin_unlock_irqrestore(&emu->reg_lock, flags);
+	return 0;
+}
+
+static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer,
+					       unsigned long *num, unsigned long *den)
+{
+	*num = 1;
+	*den = 48000;
+	return 0;
+}
+
+static struct _snd_timer_hardware snd_emu10k1_timer_hw = {
+	.flags = SNDRV_TIMER_HW_AUTO,
+	.resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
+	.ticks = 1024,
+	.start = snd_emu10k1_timer_start,
+	.stop = snd_emu10k1_timer_stop,
+	.precise_resolution = snd_emu10k1_timer_precise_resolution,
+};
+
+int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device)
+{
+	snd_timer_t *timer = NULL;
+	snd_timer_id_t tid;
+	int err;
+
+	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+	tid.card = emu->card->number;
+	tid.device = device;
+	tid.subdevice = 0;
+	if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
+		strcpy(timer->name, "EMU10K1 timer");
+		timer->private_data = emu;
+		timer->hw = snd_emu10k1_timer_hw;
+	}
+	emu->timer = timer;
+	return err;
+}




-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-11-03 21:24     ` Lee Revell
@ 2004-11-03 23:08       ` Lee Revell
  2004-11-09 14:24       ` Takashi Iwai
  1 sibling, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-11-03 23:08 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel, tiwai

On Wed, 2004-11-03 at 16:24 -0500, Lee Revell wrote:
> On Wed, 2004-11-03 at 14:43 -0500, Lee Revell wrote:
> > OK I converted this code to use the ALSA timer API.
> 

I left this out:

Signed-Off-By: Lee Revell <rlrevell@joe-job.com>

and the patch is missing a chunk:

--- alsa-orig/alsa-kernel/pci/emu10k1/Makefile	2003-02-09 13:41:56.000000000 -0500
+++ alsa/alsa-kernel/pci/emu10k1/Makefile	2004-11-03 18:07:53.000000000 -0500
@@ -5,7 +5,7 @@
 
 snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
 		    irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
-		    emuproc.o emumixer.o emufx.o
+		    emuproc.o emumixer.o emufx.o timer.o
 snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
 
 #





-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-11-03 19:43   ` [PATCH] emu10k1: add interval timer support Lee Revell
  2004-11-03 21:24     ` Lee Revell
@ 2004-11-04 17:05     ` Jaroslav Kysela
  2004-11-04 19:13       ` Lee Revell
  1 sibling, 1 reply; 35+ messages in thread
From: Jaroslav Kysela @ 2004-11-04 17:05 UTC (permalink / raw)
  To: Lee Revell; +Cc: alsa-devel, tiwai

On Wed, 3 Nov 2004, Lee Revell wrote:

> OK I converted this code to use the ALSA timer API.  This seems to work
> fine, I can access the timer from userspace.  However there does not
> seem to be an existing example of a driver that uses the ALSA timer API
> internally; all the drivers that use the interval timer internally for
> PCM period interrupts have open coded timer handling.  AFAICT the ALSA
> timer API should be OK for this purpose as well.  Is this correct?

Yes, you can use ALSA timers from kernel space as well.

> I am going to use the interval timer for multichannel PCM playback.
> This works by allocating 16 voices, setting loop stop on all of them,
> then setting the timer.  In the first timer interrupt we clear loop stop
> on all the voices with one PCI write, then re-arm the timer, and set the
> PCM running; we now have 16 voices in perfect sync.  Subsequent timer
> interrupts just call snd_pcm_period_elapsed.

If timer must be re-armed in the interrupt handler, then you have a 
problem - time shifting when the timer ack interrupt is delayed. So you 
must do a time correction.

> The above scheme could also work with an extra voice for timing but
> would be uglier.  Since the multichannel device does not have to support
> multiple open, and only 48KHZ playback, the timer seems to be a much
> cleaner solution.  Regular PCM playback will continue to use the extra
> voice.

The only one drawback is the possible delay at stream start (up to one 
period).

						Jaroslav

-----
Jaroslav Kysela <perex@suse.cz>
Linux Kernel Sound Maintainer
ALSA Project, SUSE Labs


-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-11-04 17:05     ` Jaroslav Kysela
@ 2004-11-04 19:13       ` Lee Revell
  0 siblings, 0 replies; 35+ messages in thread
From: Lee Revell @ 2004-11-04 19:13 UTC (permalink / raw)
  To: Jaroslav Kysela; +Cc: alsa-devel, tiwai

On Thu, 2004-11-04 at 18:05 +0100, Jaroslav Kysela wrote:
> On Wed, 3 Nov 2004, Lee Revell wrote:
> 
> > OK I converted this code to use the ALSA timer API.  This seems to work
> > fine, I can access the timer from userspace.  However there does not
> > seem to be an existing example of a driver that uses the ALSA timer API
> > internally; all the drivers that use the interval timer internally for
> > PCM period interrupts have open coded timer handling.  AFAICT the ALSA
> > timer API should be OK for this purpose as well.  Is this correct?
> 
> Yes, you can use ALSA timers from kernel space as well.
> 

OK.  It looks like the only current example is in the sequencer.  But
this should be good enough.

> > I am going to use the interval timer for multichannel PCM playback.
> > This works by allocating 16 voices, setting loop stop on all of them,
> > then setting the timer.  In the first timer interrupt we clear loop stop
> > on all the voices with one PCI write, then re-arm the timer, and set the
> > PCM running; we now have 16 voices in perfect sync.  Subsequent timer
> > interrupts just call snd_pcm_period_elapsed.
> 
> If timer must be re-armed in the interrupt handler, then you have a 
> problem - time shifting when the timer ack interrupt is delayed. So you 
> must do a time correction.
> 

I was planning to use the emu10k1's wallclock timer for this.

> > The above scheme could also work with an extra voice for timing but
> > would be uglier.  Since the multichannel device does not have to support
> > multiple open, and only 48KHZ playback, the timer seems to be a much
> > cleaner solution.  Regular PCM playback will continue to use the extra
> > voice.
> 
> The only one drawback is the possible delay at stream start (up to one 
> period).

Should not be a problem as this device is intended for use by JACK.

I did notice that alsa-lib/test/timer.c looks like it misses the 
first tick about half the time:

rlrevell@mindpipe:~/cvs$ ~/cvs/alsa-T3/alsa-lib/test/timer class 2, sclass 0, card 0, device 0, subdevice 0
Using timer class 2, slave class 0, card 0, device 0, subdevice 0
Timer info:
  slave = no
  card = 0
  id = 'EMU10K1'
  name = 'EMU10K1 timer'
  average resolution = 20833
Using 960 tick(s)
STATUS:
  resolution = 20833
  lost = 0
  overrun = 0
  queue = 0
TIMER: resolution = 20833ns, ticks = 1920 <--
TIMER: resolution = 20833ns, ticks = 960
TIMER: resolution = 20833ns, ticks = 960

...

Using 960 tick(s)
STATUS:
  resolution = 20833
  lost = 0
  overrun = 0
  queue = 0
TIMER: resolution = 20833ns, ticks = 960 <--
TIMER: resolution = 20833ns, ticks = 960
TIMER: resolution = 20833ns, ticks = 960

The header file mentions that when the emu10k1's timer rate is changed
you must allow 1024 sample periods before the new rate is accurate.  It
looks like SNDRV_TIMER_HW_FIRST is the answer, but this did not have any
effect.

-- 
Lee Revell <rlrevell@joe-job.com>



-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-11-03 21:24     ` Lee Revell
  2004-11-03 23:08       ` Lee Revell
@ 2004-11-09 14:24       ` Takashi Iwai
  2004-11-10  4:32         ` Lee Revell
  1 sibling, 1 reply; 35+ messages in thread
From: Takashi Iwai @ 2004-11-09 14:24 UTC (permalink / raw)
  To: Lee Revell; +Cc: Jaroslav Kysela, alsa-devel

At Wed, 03 Nov 2004 16:24:41 -0500,
Lee Revell wrote:
> 
> On Wed, 2004-11-03 at 14:43 -0500, Lee Revell wrote:
> > OK I converted this code to use the ALSA timer API.
> 
> Here is the patch against ALSA CVS.  I tested it with the ALSA from
> kernel 2.6.9-rc3-mm3 because CVS does not build currently.

The patch to include/emu10k1.h is missing, too.
Could you give it?


Takashi


-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH] emu10k1: add interval timer support
  2004-11-09 14:24       ` Takashi Iwai
@ 2004-11-10  4:32         ` Lee Revell
  2004-11-10  9:50           ` Takashi Iwai
  0 siblings, 1 reply; 35+ messages in thread
From: Lee Revell @ 2004-11-10  4:32 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: Jaroslav Kysela, alsa-devel

On Tue, 2004-11-09 at 15:24 +0100, Takashi Iwai wrote:
> At Wed, 03 Nov 2004 16:24:41 -0500,
> Lee Revell wrote:
> > 
> > On Wed, 2004-11-03 at 14:43 -0500, Lee Revell wrote:
> > > OK I converted this code to use the ALSA timer API.
> > 
> > Here is the patch against ALSA CVS.  I tested it with the ALSA from
> > kernel 2.6.9-rc3-mm3 because CVS does not build currently.
> 
> The patch to include/emu10k1.h is missing, too.
> Could you give it?
> 
> 

Sorry, here it is.

Index: alsa-kernel/include/emu10k1.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/include/emu10k1.h,v
retrieving revision 1.49
diff -u -r1.49 emu10k1.h
--- alsa-kernel/include/emu10k1.h	30 Oct 2004 07:44:19 -0000	1.49
+++ alsa-kernel/include/emu10k1.h	10 Nov 2004 04:32:30 -0000
@@ -31,6 +31,7 @@
 #include <sound/ac97_codec.h>
 #include <sound/util_mem.h>
 #include <sound/pcm-indirect.h>
+#include <sound/timer.h>
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
@@ -1000,6 +1001,8 @@
 	snd_pcm_substream_t *pcm_capture_mic_substream;
 	snd_pcm_substream_t *pcm_capture_efx_substream;
 
+	snd_timer_t *timer;
+
 	emu10k1_midi_t midi;
 	emu10k1_midi_t midi2; /* for audigy */
 
@@ -1019,6 +1022,7 @@
 int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_mixer(emu10k1_t * emu);
+int snd_emu10k1_timer(emu10k1_t * emu, int device);
 int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep);
 
 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);




-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Re: [PATCH] emu10k1: add interval timer support
  2004-11-10  4:32         ` Lee Revell
@ 2004-11-10  9:50           ` Takashi Iwai
  0 siblings, 0 replies; 35+ messages in thread
From: Takashi Iwai @ 2004-11-10  9:50 UTC (permalink / raw)
  To: Lee Revell; +Cc: Jaroslav Kysela, alsa-devel

At Tue, 09 Nov 2004 23:32:52 -0500,
Lee Revell wrote:
> 
> On Tue, 2004-11-09 at 15:24 +0100, Takashi Iwai wrote:
> > At Wed, 03 Nov 2004 16:24:41 -0500,
> > Lee Revell wrote:
> > > 
> > > On Wed, 2004-11-03 at 14:43 -0500, Lee Revell wrote:
> > > > OK I converted this code to use the ALSA timer API.
> > > 
> > > Here is the patch against ALSA CVS.  I tested it with the ALSA from
> > > kernel 2.6.9-rc3-mm3 because CVS does not build currently.
> > 
> > The patch to include/emu10k1.h is missing, too.
> > Could you give it?
> > 
> > 
> 
> Sorry, here it is.

Thanks, the patch was applied to CVS.


Takashi


-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2004-11-10  9:50 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-17  7:19 [PATCH] emu10k1: add interval timer support Lee Revell
2004-09-17  8:59 ` Jaroslav Kysela
2004-09-21 19:36   ` Lee Revell
2004-09-22 10:16     ` Takashi Iwai
2004-09-22 10:17       ` Jaroslav Kysela
2004-09-22 15:01       ` Lee Revell
2004-09-24 13:43         ` Takashi Iwai
2004-09-24 13:56           ` Jaroslav Kysela
2004-09-24 14:53             ` Paul Davis
2004-09-24 15:13               ` Takashi Iwai
2004-09-24 15:26                 ` Paul Davis
2004-09-24 15:33                   ` Takashi Iwai
2004-09-24 21:02                 ` emu10k1 multichannel playback design (was Re: [PATCH] emu10k1: add interval timer support) Lee Revell
2004-09-24 22:32                   ` Paul Davis
2004-09-24 22:57                     ` Lee Revell
2004-09-25  4:05                     ` Lee Revell
2004-09-26  0:55                   ` Lee Revell
2004-09-26  2:51                     ` Lee Revell
2004-09-26  3:10                       ` Lee Revell
2004-09-26  3:15                       ` Paul Davis
2004-09-26  3:19                         ` Lee Revell
2004-09-26  3:50                         ` Lee Revell
2004-09-26  6:50                           ` Lee Revell
2004-09-26 11:38                   ` Jaroslav Kysela
2004-09-27  0:40                     ` Lee Revell
2004-09-27  6:48                       ` Jaroslav Kysela
2004-09-27 14:35                         ` Lee Revell
2004-11-03 19:43   ` [PATCH] emu10k1: add interval timer support Lee Revell
2004-11-03 21:24     ` Lee Revell
2004-11-03 23:08       ` Lee Revell
2004-11-09 14:24       ` Takashi Iwai
2004-11-10  4:32         ` Lee Revell
2004-11-10  9:50           ` Takashi Iwai
2004-11-04 17:05     ` Jaroslav Kysela
2004-11-04 19:13       ` Lee Revell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.