OBS User unknown 2009-07-03 14:16:03 +00:00 committed by Git OBS Bridge
parent 0424a5c308
commit 8f1ec669a6
3 changed files with 270 additions and 2203 deletions

View File

@ -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;

View File

@ -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

2204
alsa.spec

File diff suppressed because it is too large Load Diff