diff -ru alsa-48/alsa-kernel/include/emu10k1.h alsa-old/alsa-kernel/include/emu10k1.h
--- alsa-48/alsa-kernel/include/emu10k1.h	2005-02-06 13:46:51.000000000 -0500
+++ alsa-old/alsa-kernel/include/emu10k1.h	2005-02-06 09:27:06.000000000 -0500
@@ -279,12 +279,12 @@
 #define A_IOCFG_DISABLE_AC97_FRONT      0x0080  /* turn off ac97 front -> front (10k2.1)	*/
 #define A_IOCFG_GPOUT1		0x0002		/* IR? drive's internal bypass (?)		*/
 #define A_IOCFG_GPOUT2		0x0001		/* IR */
+#define A_IOCFG_DIGITAL_JACK    0x1000          /* digital for a2 platinum			*/
+#define A_IOCFG_REAR_JACK       0x8000		/* analog rear					*/
+#define A_IOCFG_FRONT_JACK      0x4000		/* analog front					*/
 #define A_IOCFG_MULTIPURPOSE_JACK	0x2000  /* center+lfe+rear_center (a2/a2ex)		*/
                                                 /* + digital for generic 10k2			*/
-#define A_IOCFG_DIGITAL_JACK    0x1000          /* digital for a2 platinum			*/
-#define A_IOCFG_FRONT_JACK      0x4000
-#define A_IOCFG_REAR_JACK       0x8000
-#define A_IOCFG_PHONES_JACK     0x0100          /* LiveDrive					*/
+#define A_IOCFG_PHONES_JACK     0x0100          /* LiveDrive headphones				*/
 
 /* outputs:
  *	for audigy2 platinum:	0xa00
@@ -789,9 +789,10 @@
 #define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
 
 #define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
-#define A_SPDIF_48000		0x00000080
-#define A_SPDIF_44100		0x00000000
-#define A_SPDIF_96000		0x00000040
+#define A_SPDIF_RATE_MASK	0x000000c0
+#define A_SPDIF_48000		0x00000000
+#define A_SPDIF_44100		0x00000040
+#define A_SPDIF_96000		0x00000080
 
 /* 0x77,0x78,0x79 "something i2s-related" - default to 0x01080000 on my audigy 2 ZS --rlrevell	*/
 /* 0x7a, 0x7b - lookup tables */
diff -ru alsa-48/alsa-kernel/pci/emu10k1/emumixer.c alsa-old/alsa-kernel/pci/emu10k1/emumixer.c
--- alsa-48/alsa-kernel/pci/emu10k1/emumixer.c	2005-02-06 13:46:51.000000000 -0500
+++ alsa-old/alsa-kernel/pci/emu10k1/emumixer.c	2005-02-06 10:15:04.000000000 -0500
@@ -67,6 +67,92 @@
 	return 0;
 }
 
+static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = {"44100", "48000", "96000"};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_audigy_spdif_output_rate_get(snd_kcontrol_t * kcontrol,
+                                 snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int tmp;
+	unsigned long flags;
+	
+
+	spin_lock_irqsave(&emu->reg_lock, flags);
+	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
+	switch (tmp & A_SPDIF_RATE_MASK) {
+	case A_SPDIF_44100:
+		ucontrol->value.enumerated.item[0] = 0;
+		break;
+	case A_SPDIF_48000:
+		ucontrol->value.enumerated.item[0] = 1;
+		break;
+	case A_SPDIF_96000:
+		ucontrol->value.enumerated.item[0] = 2;
+		break;
+	default:
+		ucontrol->value.enumerated.item[0] = 1;
+	}
+	spin_unlock_irqrestore(&emu->reg_lock, flags);
+	return 0;
+}
+
+static int snd_audigy_spdif_output_rate_put(snd_kcontrol_t * kcontrol,
+                                 snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	int change;
+	unsigned int reg, val, tmp;
+	unsigned long flags;
+
+	switch(ucontrol->value.enumerated.item[0]) {
+	case 0:
+		val = A_SPDIF_44100;
+		break;
+	case 1:
+		val = A_SPDIF_48000;
+		break;
+	case 2:
+		val = A_SPDIF_96000;
+		break;
+	default:
+		val = A_SPDIF_48000;
+		break;
+	}
+
+	
+	spin_lock_irqsave(&emu->reg_lock, flags);
+	reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
+	tmp = reg & ~A_SPDIF_RATE_MASK;
+	tmp |= val;
+	if (change = (tmp != reg)) {
+		snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
+	}
+	spin_unlock_irqrestore(&emu->reg_lock, flags);
+	return change;
+}
+
+static snd_kcontrol_new_t snd_audigy_spdif_output_rate =
+{
+	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         "Audigy SPDIF Output Sample Rate",
+	.count =	1,
+	.info =         snd_audigy_spdif_output_rate_info,
+	.get =          snd_audigy_spdif_output_rate_get,
+	.put =          snd_audigy_spdif_output_rate_put
+};
+
 static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
                                  snd_ctl_elem_value_t * ucontrol)
 {
@@ -842,6 +928,10 @@
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
 			return err;
+		if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
+			return -ENOMEM;
+		if ((err = snd_ctl_add(card, kctl)))
+			return err;
 	} else if (! emu->APS) {
 		/* sb live! */
 		if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
Only in alsa-old/alsa-kernel/pci/emu10k1: emumixer.c~
diff -ru alsa-48/alsa-kernel/pci/emu10k1/emupcm.c alsa-old/alsa-kernel/pci/emu10k1/emupcm.c
--- alsa-48/alsa-kernel/pci/emu10k1/emupcm.c	2005-02-06 13:46:51.000000000 -0500
+++ alsa-old/alsa-kernel/pci/emu10k1/emupcm.c	2005-02-06 13:44:11.000000000 -0500
@@ -235,6 +235,7 @@
 
 static unsigned int emu10k1_select_interprom(unsigned int pitch_target)
 {
+	
 	if (pitch_target == PITCH_48000)
 		return CCCA_INTERPROM_0;
 	else if (pitch_target < PITCH_48000)
@@ -677,7 +678,7 @@
 {
 	snd_pcm_substream_t *substream;
 	snd_pcm_runtime_t *runtime;
-	unsigned int voice, pitch, pitch_target, tmp;
+	unsigned int voice, pitch, pitch_target;
 
 	if (evoice == NULL)	/* skip second voice for mono */
 		return;
@@ -946,9 +947,9 @@
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000,
 	.rate_min =		4000,
-	.rate_max =		48000,
+	.rate_max =		96000,
 	.channels_min =		1,
 	.channels_max =		2,
 	.buffer_bytes_max =	(128*1024),
diff -ru alsa-48/alsa-kernel/pci/emu10k1/emuproc.c alsa-old/alsa-kernel/pci/emu10k1/emuproc.c
--- alsa-48/alsa-kernel/pci/emu10k1/emuproc.c	2005-02-06 13:46:51.000000000 -0500
+++ alsa-old/alsa-kernel/pci/emu10k1/emuproc.c	2005-02-05 23:26:59.000000000 -0500
@@ -140,38 +140,38 @@
 		/* 29 */ "???",
 		/* 30 */ "???",
 		/* 31 */ "???",
-		/* 32 */ "???",
-		/* 33 */ "???",
-		/* 34 */ "???",
-		/* 35 */ "???",
-		/* 36 */ "???",
-		/* 37 */ "???",
-		/* 38 */ "???",
-		/* 39 */ "???",
-		/* 40 */ "???",
-		/* 41 */ "???",
-		/* 42 */ "???",
-		/* 43 */ "???",
-		/* 44 */ "???",
-		/* 45 */ "???",
-		/* 46 */ "???",
-		/* 47 */ "???",
-		/* 48 */ "???",
-		/* 49 */ "???",
-		/* 50 */ "???",
-		/* 51 */ "???",
-		/* 52 */ "???",
-		/* 53 */ "???",
-		/* 54 */ "???",
-		/* 55 */ "???",
-		/* 56 */ "???",
-		/* 57 */ "???",
-		/* 58 */ "???",
-		/* 59 */ "???",
-		/* 60 */ "???",
-		/* 61 */ "???",
-		/* 62 */ "???",
-		/* 33 */ "???"
+		/* 32 */ "FXBUS2_0",
+		/* 33 */ "FXBUS2_1",
+		/* 34 */ "FXBUS2_2",
+		/* 35 */ "FXBUS2_3",
+		/* 36 */ "FXBUS2_4",
+		/* 37 */ "FXBUS2_5",
+		/* 38 */ "FXBUS2_6",
+		/* 39 */ "FXBUS2_7",
+		/* 40 */ "FXBUS2_8",
+		/* 41 */ "FXBUS2_9",
+		/* 42 */ "FXBUS2_10",
+		/* 43 */ "FXBUS2_11",
+		/* 44 */ "FXBUS2_12",
+		/* 45 */ "FXBUS2_13",
+		/* 46 */ "FXBUS2_14",
+		/* 47 */ "FXBUS2_15",
+		/* 48 */ "FXBUS2_16",
+		/* 49 */ "FXBUS2_17",
+		/* 50 */ "FXBUS2_18",
+		/* 51 */ "FXBUS2_19",
+		/* 52 */ "FXBUS2_20",
+		/* 53 */ "FXBUS2_21",
+		/* 54 */ "FXBUS2_22",
+		/* 55 */ "FXBUS2_23",
+		/* 56 */ "FXBUS2_24",
+		/* 57 */ "FXBUS2_25",
+		/* 58 */ "FXBUS2_26",
+		/* 59 */ "FXBUS2_27",
+		/* 60 */ "FXBUS2_28",
+		/* 61 */ "FXBUS2_29",
+		/* 62 */ "FXBUS2_30",
+		/* 63 */ "FXBUS2_31"
 	};
 
 	emu10k1_t *emu = entry->private_data;
@@ -221,7 +221,7 @@
 			snd_iprintf(buffer, "  Output %02i [%s]\n", idx, outputs[idx]);
 	}
 	snd_iprintf(buffer, "\nAll FX Outputs        :\n");
-	for (idx = 0; idx < 32; idx++)
+	for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++)
 		snd_iprintf(buffer, "  Output %02i [%s]\n", idx, outputs[idx]);
 	snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 0", SPCS0, -1);
 	snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 1", SPCS1, -1);
@@ -322,6 +322,26 @@
 	return 0;
 }
 
+static void snd_emu10k1_proc_voices_read(snd_info_entry_t *entry, 
+				  snd_info_buffer_t * buffer)
+{
+	emu10k1_t *emu = entry->private_data;
+	emu10k1_voice_t *voice;
+	int idx;
+	
+	snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n");
+	for (idx = 0; idx < NUM_G; idx++) {
+		voice = &emu->voices[idx];
+		snd_iprintf(buffer, "%i\t%i\t%i\t%i\t%i\t%i\n",
+			idx,
+			voice->use,
+			voice->pcm,
+			voice->efx,
+			voice->synth,
+			voice->midi);
+	}
+}
+
 #ifdef CONFIG_SND_DEBUG
 static void snd_emu_proc_io_reg_read(snd_info_entry_t *entry,
 				     snd_info_buffer_t * buffer)
@@ -506,6 +526,9 @@
 	if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
 		snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read);
 
+	if (! snd_card_proc_new(emu->card, "voices", &entry))
+		snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read);
+
 	if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
diff -ru alsa-48/alsa-kernel/pci/emu10k1/voice.c alsa-old/alsa-kernel/pci/emu10k1/voice.c
--- alsa-48/alsa-kernel/pci/emu10k1/voice.c	2005-02-06 13:46:51.000000000 -0500
+++ alsa-old/alsa-kernel/pci/emu10k1/voice.c	2005-02-06 05:16:49.000000000 -0500
@@ -48,47 +48,50 @@
 static int voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
 {
 	emu10k1_voice_t *voice;
-	int idx, pair, i, j, k, first_voice, last_voice, skip;
+	int i, j, k, first_voice, last_voice, skip;
 
-	first_voice = last_voice = skip = 0;	
 	*rvoice = NULL;
-	for (i = emu->next_free_voice, j=0; j < NUM_G ; i += number, j+= number) {
+	first_voice = last_voice = 0;
+	for (i = emu->next_free_voice, j = 0; j < NUM_G ; i += number, j += number) {
 		// printk("i %d j %d next free %d!\n", i, j, emu->next_free_voice);
 		i %= NUM_G;
-		if ((i % 2) && (number == 2)) {
+
+		/* stereo voices must be even/odd */
+		if ((number == 2) && (i % 2)) {
 			i++;
 			continue;
 		}
 			
 		/* make sure the block of voices does not cross the 32 voice boundary */
-		if (((i % 32) + number) > 32)
-			continue;
+		//if (((i % 32) + number) > 32)
+		//	continue;
+
+		skip = 0;
 		for (k = 0; k < number; k++) {
-			voice = &emu->voices[i+k];
+			voice = &emu->voices[(i+k) % NUM_G];
 			if (voice->use) {
-				// printk("voice %d: use=1!\n", i+k);
+				printk("voice %d: use=1!\n", i+k);
 				skip = 1;
 			}
 		}
 		if (!skip) {
 			// printk("allocated voice %d\n", i);
 			first_voice = i;
-			last_voice = i + number;
+			last_voice = (i + number) % NUM_G;
 			emu->next_free_voice = last_voice;
-			emu->next_free_voice %= NUM_G;
 			break;
 		}
 	}
 	
 	if (first_voice == last_voice) {
-		printk("first==last, number %d, next free %d!\n", number, emu->next_free_voice);
-		/* BUG (or not enough voices)! */
+		printk("BUG (or not enough voices), number %d, next free %d!\n",
+				number,
+				emu->next_free_voice);
 		return -ENOMEM;
 	}	
 	
-	pair = ( number == 2 ) ? 1 : 0;
-	for (idx=first_voice; idx < last_voice; idx++) {
-		voice = &emu->voices[idx];
+	for (i=0; i < number; i++) {
+		voice = &emu->voices[(first_voice + i) % NUM_G];
 		// printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number);
 		voice->use = 1;
 		switch (type) {

