This commit is contained in:
parent
0424a5c308
commit
8f1ec669a6
@ -1,3 +1,18 @@
|
||||
diff --git a/include/control.h b/include/control.h
|
||||
index 2361dc3..29ea397 100644
|
||||
--- a/include/control.h
|
||||
+++ b/include/control.h
|
||||
@@ -174,6 +174,10 @@ typedef enum _snd_ctl_event_type {
|
||||
#define SND_CTL_TLVT_DB_LINEAR 0x0002
|
||||
/** TLV type - dB range container */
|
||||
#define SND_CTL_TLVT_DB_RANGE 0x0003
|
||||
+/** TLV type - dB scale specified by min/max values */
|
||||
+#define SND_CTL_TLVT_DB_MINMAX 0x0004
|
||||
+/** TLV type - dB scale specified by min/max values (with mute) */
|
||||
+#define SND_CTL_TLVT_DB_MINMAX_MUTE 0x0005
|
||||
|
||||
/** Mute state */
|
||||
#define SND_CTL_TLV_DB_GAIN_MUTE -9999999
|
||||
diff --git a/include/pcm_rate.h b/include/pcm_rate.h
|
||||
index d211e09..4d70df2 100644
|
||||
--- a/include/pcm_rate.h
|
||||
@ -269,6 +284,220 @@ index 4d2c739..0bb8f86 100644
|
||||
for (card = 0; card < 32; card++) {
|
||||
#ifdef SUPPORT_ALOAD
|
||||
if (! snd_card_load(card))
|
||||
diff --git a/src/control/tlv.c b/src/control/tlv.c
|
||||
index 0006a87..7627f57 100644
|
||||
--- a/src/control/tlv.c
|
||||
+++ b/src/control/tlv.c
|
||||
@@ -89,6 +89,8 @@ int snd_tlv_parse_dB_info(unsigned int *tlv,
|
||||
}
|
||||
break;
|
||||
case SND_CTL_TLVT_DB_SCALE:
|
||||
+ case SND_CTL_TLVT_DB_MINMAX:
|
||||
+ case SND_CTL_TLVT_DB_MINMAX_MUTE:
|
||||
#ifndef HAVE_SOFT_FLOAT
|
||||
case SND_CTL_TLVT_DB_LINEAR:
|
||||
#endif
|
||||
@@ -165,6 +167,8 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax,
|
||||
*max = *min + (long)(step * (rangemax - rangemin));
|
||||
return 0;
|
||||
}
|
||||
+ case SND_CTL_TLVT_DB_MINMAX:
|
||||
+ case SND_CTL_TLVT_DB_MINMAX_MUTE:
|
||||
case SND_CTL_TLVT_DB_LINEAR:
|
||||
*min = (int)tlv[2];
|
||||
*max = (int)tlv[3];
|
||||
@@ -214,6 +218,23 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax,
|
||||
*db_gain = (volume - rangemin) * step + min;
|
||||
return 0;
|
||||
}
|
||||
+ case SND_CTL_TLVT_DB_MINMAX:
|
||||
+ case SND_CTL_TLVT_DB_MINMAX_MUTE: {
|
||||
+ int mindb, maxdb;
|
||||
+ mindb = tlv[2];
|
||||
+ maxdb = tlv[3];
|
||||
+ if (volume <= rangemin || rangemax <= rangemin) {
|
||||
+ if (tlv[0] == SND_CTL_TLVT_DB_MINMAX_MUTE)
|
||||
+ *db_gain = SND_CTL_TLV_DB_GAIN_MUTE;
|
||||
+ else
|
||||
+ *db_gain = mindb;
|
||||
+ } else if (volume >= rangemax)
|
||||
+ *db_gain = maxdb;
|
||||
+ else
|
||||
+ *db_gain = (maxdb - mindb) * (volume - rangemin) /
|
||||
+ (rangemax - rangemin) + mindb;
|
||||
+ return 0;
|
||||
+ }
|
||||
#ifndef HAVE_SOFT_FLOAT
|
||||
case SND_CTL_TLVT_DB_LINEAR: {
|
||||
int mindb = tlv[2];
|
||||
@@ -297,6 +318,24 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+ case SND_CTL_TLVT_DB_MINMAX:
|
||||
+ case SND_CTL_TLVT_DB_MINMAX_MUTE: {
|
||||
+ int min, max;
|
||||
+ min = tlv[2];
|
||||
+ max = tlv[3];
|
||||
+ if (db_gain <= min)
|
||||
+ *value = rangemin;
|
||||
+ else if (db_gain >= max)
|
||||
+ *value = rangemax;
|
||||
+ else {
|
||||
+ long v = (db_gain - min) * (rangemax - rangemin);
|
||||
+ if (xdir > 0)
|
||||
+ v += (max - min) - 1;
|
||||
+ v = v / (max - min) + rangemin;
|
||||
+ *value = v;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
#ifndef HAVE_SOFT_FLOAT
|
||||
case SND_CTL_TLVT_DB_LINEAR: {
|
||||
int min, max;
|
||||
diff --git a/src/pcm/pcm_dmix_i386.h b/src/pcm/pcm_dmix_i386.h
|
||||
index 9ea155d..462371a 100644
|
||||
--- a/src/pcm/pcm_dmix_i386.h
|
||||
+++ b/src/pcm/pcm_dmix_i386.h
|
||||
@@ -400,8 +400,8 @@ static void MIX_AREAS_24(unsigned int size,
|
||||
"\tmovzwl (%%esi), %%ecx\n"
|
||||
"\tmovl (%%ebx), %%edx\n"
|
||||
"\tsall $16, %%eax\n"
|
||||
+ "\torl %%eax, %%ecx\n"
|
||||
"\t" LOCK_PREFIX "btsw $0, (%%edi)\n"
|
||||
- "\tleal (%%ecx,%%eax,1), %%ecx\n"
|
||||
"\tjc 2f\n"
|
||||
"\t" XSUB " %%edx, %%ecx\n"
|
||||
"2:"
|
||||
diff --git a/src/pcm/pcm_dmix_x86_64.h b/src/pcm/pcm_dmix_x86_64.h
|
||||
index b4d0a41..ab40f50 100644
|
||||
--- a/src/pcm/pcm_dmix_x86_64.h
|
||||
+++ b/src/pcm/pcm_dmix_x86_64.h
|
||||
@@ -284,11 +284,11 @@ static void MIX_AREAS_24(unsigned int size,
|
||||
* *sum += sample;
|
||||
*/
|
||||
"\tmovsbl 2(%%rsi), %%eax\n"
|
||||
- "\tmovswl (%%rsi), %%ecx\n"
|
||||
+ "\tmovzwl (%%rsi), %%ecx\n"
|
||||
"\tmovl (%%rbx), %%edx\n"
|
||||
"\tsall $16, %%eax\n"
|
||||
+ "\torl %%eax, %%ecx\n"
|
||||
"\t" LOCK_PREFIX "btsw $0, (%%rdi)\n"
|
||||
- "\t.byte 0x67, 0x8d, 0x0c, 0x01\n"
|
||||
"\tjc 2f\n"
|
||||
"\t" XSUB " %%edx, %%ecx\n"
|
||||
"2:"
|
||||
diff --git a/src/pcm/pcm_hooks.c b/src/pcm/pcm_hooks.c
|
||||
index 826685f..2fbee73 100644
|
||||
--- a/src/pcm/pcm_hooks.c
|
||||
+++ b/src/pcm/pcm_hooks.c
|
||||
@@ -43,12 +43,39 @@ struct _snd_pcm_hook {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
+struct snd_pcm_hook_dllist {
|
||||
+ void *dlobj;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
typedef struct {
|
||||
snd_pcm_generic_t gen;
|
||||
struct list_head hooks[SND_PCM_HOOK_TYPE_LAST + 1];
|
||||
+ struct list_head dllist;
|
||||
} snd_pcm_hooks_t;
|
||||
#endif
|
||||
|
||||
+static int hook_add_dlobj(snd_pcm_t *pcm, void *dlobj)
|
||||
+{
|
||||
+ snd_pcm_hooks_t *h = pcm->private_data;
|
||||
+ struct snd_pcm_hook_dllist *dl;
|
||||
+
|
||||
+ dl = malloc(sizeof(*dl));
|
||||
+ if (!dl)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dl->dlobj = dlobj;
|
||||
+ list_add_tail(&dl->list, &h->dllist);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void hook_remove_dlobj(struct snd_pcm_hook_dllist *dl)
|
||||
+{
|
||||
+ list_del(&dl->list);
|
||||
+ snd_dlclose(dl->dlobj);
|
||||
+ free(dl);
|
||||
+}
|
||||
+
|
||||
static int snd_pcm_hooks_close(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
@@ -71,6 +98,11 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
|
||||
snd_pcm_hook_remove(hook);
|
||||
}
|
||||
}
|
||||
+ while (!list_empty(&h->dllist)) {
|
||||
+ struct snd_pcm_hook_dllist *dl;
|
||||
+ pos = h->dllist.next;
|
||||
+ hook_remove_dlobj(list_entry(pos, struct snd_pcm_hook_dllist, list));
|
||||
+ }
|
||||
err = snd_pcm_generic_close(pcm);
|
||||
if (err < 0)
|
||||
res = err;
|
||||
@@ -193,6 +225,7 @@ int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
|
||||
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
|
||||
INIT_LIST_HEAD(&h->hooks[k]);
|
||||
}
|
||||
+ INIT_LIST_HEAD(&h->dllist);
|
||||
err = snd_pcm_new(&pcm, SND_PCM_TYPE_HOOKS, name, slave->stream, slave->mode);
|
||||
if (err < 0) {
|
||||
free(h);
|
||||
@@ -312,6 +345,8 @@ static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_
|
||||
snd_config_iterator_t i, next;
|
||||
int (*install_func)(snd_pcm_t *pcm, snd_config_t *args) = NULL;
|
||||
void *h = NULL;
|
||||
+ struct snd_pcm_hook_dllist *dl;
|
||||
+
|
||||
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
|
||||
SNDERR("Invalid hook definition");
|
||||
return -EINVAL;
|
||||
@@ -402,20 +437,26 @@ static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_
|
||||
_err:
|
||||
if (type)
|
||||
snd_config_delete(type);
|
||||
- if (err >= 0) {
|
||||
- if (args && snd_config_get_string(args, &str) >= 0) {
|
||||
- err = snd_config_search_definition(root, "hook_args", str, &args);
|
||||
- if (err < 0)
|
||||
- SNDERR("unknown hook_args %s", str);
|
||||
- else
|
||||
- err = install_func(pcm, args);
|
||||
- snd_config_delete(args);
|
||||
- } else
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+
|
||||
+ if (args && snd_config_get_string(args, &str) >= 0) {
|
||||
+ err = snd_config_search_definition(root, "hook_args", str, &args);
|
||||
+ if (err < 0)
|
||||
+ SNDERR("unknown hook_args %s", str);
|
||||
+ else
|
||||
err = install_func(pcm, args);
|
||||
+ snd_config_delete(args);
|
||||
+ } else
|
||||
+ err = install_func(pcm, args);
|
||||
+
|
||||
+ if (err >= 0)
|
||||
+ err = hook_add_dlobj(pcm, h);
|
||||
+
|
||||
+ if (err < 0) {
|
||||
snd_dlclose(h);
|
||||
- }
|
||||
- if (err < 0)
|
||||
return err;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
|
||||
index a97a5de..c28884b 100644
|
||||
--- a/src/pcm/pcm_rate.c
|
||||
@ -408,3 +637,30 @@ index 20e119b..8b2d2d0 100644
|
||||
rate = calloc(1, sizeof(*rate));
|
||||
if (! rate)
|
||||
return -ENOMEM;
|
||||
diff --git a/src/seq/seq_midi_event.c b/src/seq/seq_midi_event.c
|
||||
index b5caa1b..53d0572 100644
|
||||
--- a/src/seq/seq_midi_event.c
|
||||
+++ b/src/seq/seq_midi_event.c
|
||||
@@ -442,6 +442,7 @@ long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count
|
||||
|
||||
|
||||
if (cmd == MIDI_CMD_COMMON_SYSEX) {
|
||||
+ snd_midi_event_reset_decode(dev);
|
||||
qlen = ev->data.ext.len;
|
||||
if (count < qlen)
|
||||
return -ENOMEM;
|
||||
@@ -566,10 +567,10 @@ static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int coun
|
||||
if (dev->nostat && count < 12)
|
||||
return -ENOMEM;
|
||||
cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
|
||||
- bytes[0] = ev->data.control.param & 0x007f;
|
||||
- bytes[1] = (ev->data.control.param & 0x3f80) >> 7;
|
||||
- bytes[2] = ev->data.control.value & 0x007f;
|
||||
- bytes[3] = (ev->data.control.value & 0x3f80) >> 7;
|
||||
+ bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
|
||||
+ bytes[1] = ev->data.control.param & 0x007f;
|
||||
+ bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
|
||||
+ bytes[3] = ev->data.control.value & 0x007f;
|
||||
if (cmd != dev->lastcmd && !dev->nostat) {
|
||||
if (count < 9)
|
||||
return -ENOMEM;
|
||||
|
13
alsa.changes
13
alsa.changes
@ -1,3 +1,16 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Jun 30 11:22:08 CEST 2009 - tiwai@suse.de
|
||||
|
||||
- Manage dlobj lifetime in pcm_hooks.c
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jun 24 12:27:20 CEST 2009 - tiwai@suse.de
|
||||
|
||||
- seq_midi_event: fix decoding of (N)RPN events
|
||||
- MIDI event decoder: prevent running status after sysex
|
||||
- pcm dmix: fix MIX_AREAS_24 routine for i386 & x86_64 platforms
|
||||
- Add the support of TLV_DB_MINMAX types
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jun 9 04:51:57 CEST 2009 - tiwai@suse.de
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user