Alsa-devel
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
February 2021
- 114 participants
- 288 discussions
[PATCH] ALSA: usb-audio: Allow modifying parameters with succeeding hw_params calls
by Takashi Iwai 28 Feb '21
by Takashi Iwai 28 Feb '21
28 Feb '21
The recent fix for the hw constraints for implicit feedback streams
via commit e4ea77f8e53f ("ALSA: usb-audio: Always apply the hw
constraints for implicit fb sync") added the check of the matching
endpoints and whether those EPs are already opened. This is needed
and correct, per se, even for the normal streams without the implicit
feedback, as the endpoint setup is exclusive.
However, it's reported that there seem applications that behave in
unexpected ways to update the hw_params without clearing the previous
setup via hw_free, and those hit a problem now: then hw_params is
called with still the previous EP setup kept, hence it's restricted
with the previous own setup. Although the obvious fix is to call
snd_pcm_hw_free() API in the application side, it's a kind of
unwelcome change.
This patch tries to ease the situation: in the endpoint check, we add
a couple of more conditions and now skip the endpoint that is being
used only by the stream in question itself. That is, in addition to
the presence check of ep (ep->cur_audiofmt is non-NULL), when the
following conditions are met, we skip such an ep:
- ep->opened == 1, and
- ep->cur_audiofmt == subs->cur_audiofmt.
subs->cur_audiofmt is non-NULL only if it's a re-setup of hw_params,
and ep->cur_audiofmt points to the currently set up parameters. So if
those match, it must be this stream itself.
Fixes: e4ea77f8e53f ("ALSA: usb-audio: Always apply the hw constraints for implicit fb sync")
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211941
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
---
sound/usb/pcm.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index bf5a0f3c1fad..e5311b6bb3f6 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -845,13 +845,19 @@ get_sync_ep_from_substream(struct snd_usb_substream *subs)
list_for_each_entry(fp, &subs->fmt_list, list) {
ep = snd_usb_get_endpoint(chip, fp->endpoint);
- if (ep && ep->cur_rate)
- return ep;
+ if (ep && ep->cur_audiofmt) {
+ /* if EP is already opened solely for this substream,
+ * we still allow us to change the parameter; otherwise
+ * this substream has to follow the existing parameter
+ */
+ if (ep->cur_audiofmt != subs->cur_audiofmt || ep->opened > 1)
+ return ep;
+ }
if (!fp->implicit_fb)
continue;
/* for the implicit fb, check the sync ep as well */
ep = snd_usb_get_endpoint(chip, fp->sync_ep);
- if (ep && ep->cur_rate)
+ if (ep && ep->cur_audiofmt)
return ep;
}
return NULL;
--
2.26.2
1
0
28 Feb '21
This commit reverts 0bf6276392e9 ("x32: Warn and disable rather than
error if binutils too old").
The help text in arch/x86/Kconfig says enabling the X32 ABI support
needs binutils 2.22 or later. This is met because the minimal binutils
version is 2.23 according to Documentation/process/changes.rst.
I would not say I am not familiar with toolchain configuration, but
I checked the configure.tgt code in binutils. The elf32_x86_64
emulation mode seems to be included when it is configured for the
x86_64-*-linux-* target.
I also tried lld and llvm-objcopy, and succeeded in building x32 VDSO.
I removed the compile-time check in arch/x86/Makefile, in the hope of
elf32_x86_64 being always supported.
With this, CONFIG_X86_X32 and CONFIG_X86_X32_ABI will be equivalent.
Rename the former to the latter.
Signed-off-by: Masahiro Yamada <masahiroy(a)kernel.org>
---
arch/x86/Kconfig | 8 ++------
arch/x86/Makefile | 16 ----------------
arch/x86/include/asm/syscall_wrapper.h | 6 +++---
arch/x86/include/asm/vdso.h | 2 +-
arch/x86/kernel/process_64.c | 2 +-
fs/fuse/file.c | 2 +-
fs/xfs/xfs_ioctl32.c | 2 +-
sound/core/control_compat.c | 16 ++++++++--------
sound/core/pcm_compat.c | 20 ++++++++++----------
9 files changed, 27 insertions(+), 47 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2792879d398e..7272cba2744c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2865,7 +2865,7 @@ config IA32_AOUT
help
Support old a.out binaries in the 32bit emulation.
-config X86_X32
+config X86_X32_ABI
bool "x32 ABI for 64-bit mode"
depends on X86_64
help
@@ -2874,10 +2874,6 @@ config X86_X32
full 64-bit register file and wide data path while leaving
pointers at 32 bits for smaller memory footprint.
- You will need a recent binutils (2.22 or later) with
- elf32_x86_64 support enabled to compile a kernel with this
- option set.
-
config COMPAT_32
def_bool y
depends on IA32_EMULATION || X86_32
@@ -2886,7 +2882,7 @@ config COMPAT_32
config COMPAT
def_bool y
- depends on IA32_EMULATION || X86_X32
+ depends on IA32_EMULATION || X86_X32_ABI
if COMPAT
config COMPAT_FOR_U64_ALIGNMENT
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 2d6d5a28c3bf..e163549f5be7 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -125,22 +125,6 @@ else
KBUILD_CFLAGS += -mcmodel=kernel
endif
-ifdef CONFIG_X86_X32
- x32_ld_ok := $(call try-run,\
- /bin/echo -e '1: .quad 1b' | \
- $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
- $(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMPO" && \
- $(LD) -m elf32_x86_64 "$$TMPO" -o "$$TMP",y,n)
- ifeq ($(x32_ld_ok),y)
- CONFIG_X86_X32_ABI := y
- KBUILD_AFLAGS += -DCONFIG_X86_X32_ABI
- KBUILD_CFLAGS += -DCONFIG_X86_X32_ABI
- else
- $(warning CONFIG_X86_X32 enabled but no binutils support)
- endif
-endif
-export CONFIG_X86_X32_ABI
-
#
# If the function graph tracer is used with mcount instead of fentry,
# '-maccumulate-outgoing-args' is needed to prevent a GCC bug
diff --git a/arch/x86/include/asm/syscall_wrapper.h b/arch/x86/include/asm/syscall_wrapper.h
index a84333adeef2..69bf87c41a0b 100644
--- a/arch/x86/include/asm/syscall_wrapper.h
+++ b/arch/x86/include/asm/syscall_wrapper.h
@@ -158,7 +158,7 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
#endif /* CONFIG_IA32_EMULATION */
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
/*
* For the x32 ABI, we need to create a stub for compat_sys_*() which is aware
* of the x86-64-style parameter ordering of x32 syscalls. The syscalls common
@@ -176,12 +176,12 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
#define __X32_COMPAT_SYS_NI(name) \
__SYS_NI(x32, compat_sys_##name)
-#else /* CONFIG_X86_X32 */
+#else /* CONFIG_X86_X32_ABI */
#define __X32_COMPAT_SYS_STUB0(name)
#define __X32_COMPAT_SYS_STUBx(x, name, ...)
#define __X32_COMPAT_COND_SYSCALL(name)
#define __X32_COMPAT_SYS_NI(name)
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
#ifdef CONFIG_COMPAT
diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h
index 98aa103eb4ab..2963a2f5dbc4 100644
--- a/arch/x86/include/asm/vdso.h
+++ b/arch/x86/include/asm/vdso.h
@@ -37,7 +37,7 @@ struct vdso_image {
extern const struct vdso_image vdso_image_64;
#endif
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
extern const struct vdso_image vdso_image_x32;
#endif
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index d08307df69ad..a93b6f4296fc 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -656,7 +656,7 @@ void set_personality_64bit(void)
static void __set_personality_x32(void)
{
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
if (current->mm)
current->mm->context.flags = 0;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 8cccecb55fb8..c53c620d1a7a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2797,7 +2797,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
#else
if (flags & FUSE_IOCTL_COMPAT) {
inarg.flags |= FUSE_IOCTL_32BIT;
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
if (in_x32_syscall())
inarg.flags |= FUSE_IOCTL_COMPAT_X32;
#endif
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 33c09ec8e6c0..e8038bc966e7 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -233,7 +233,7 @@ xfs_compat_ioc_fsbulkstat(
inumbers_fmt_pf inumbers_func = xfs_fsinumbers_fmt_compat;
bulkstat_one_fmt_pf bs_one_func = xfs_fsbulkstat_one_fmt_compat;
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
if (in_x32_syscall()) {
/*
* ... but on x32 the input xfs_fsop_bulkreq has pointers
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 1d708aab9c98..5d1b94bda2cd 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -153,7 +153,7 @@ struct snd_ctl_elem_value32 {
unsigned char reserved[128];
};
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
/* x32 has a different alignment for 64bit values from ia32 */
struct snd_ctl_elem_value_x32 {
struct snd_ctl_elem_id id;
@@ -165,7 +165,7 @@ struct snd_ctl_elem_value_x32 {
} value;
unsigned char reserved[128];
};
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
/* get the value type and count of the control */
static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
@@ -350,7 +350,7 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
return ctl_elem_write_user(file, data32, &data32->value);
}
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
static int snd_ctl_elem_read_user_x32(struct snd_card *card,
struct snd_ctl_elem_value_x32 __user *data32)
{
@@ -362,7 +362,7 @@ static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
{
return ctl_elem_write_user(file, data32, &data32->value);
}
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
/* add or replace a user control */
static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
@@ -421,10 +421,10 @@ enum {
SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
};
static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -463,12 +463,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
return snd_ctl_elem_add_compat(ctl, argp, 0);
case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
return snd_ctl_elem_add_compat(ctl, argp, 1);
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
case SNDRV_CTL_IOCTL_ELEM_READ_X32:
return snd_ctl_elem_read_user_x32(ctl->card, argp);
case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
return snd_ctl_elem_write_user_x32(ctl, argp);
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
}
down_read(&snd_ioctl_rwsem);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 590a46a9e78d..937f5117a81f 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -147,13 +147,13 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream
return err;
}
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
struct snd_pcm_channel_info __user *src);
#define snd_pcm_ioctl_channel_info_x32(s, p) \
snd_pcm_channel_info_user(s, p)
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
struct compat_snd_pcm_status64 {
snd_pcm_state_t state;
@@ -373,7 +373,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
return err;
}
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
/* X32 ABI has 64bit timespec and 64bit alignment */
struct snd_pcm_mmap_status_x32 {
snd_pcm_state_t state;
@@ -464,7 +464,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
return 0;
}
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
/*
*/
@@ -484,10 +484,10 @@ enum {
SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
SNDRV_PCM_IOCTL_STATUS_COMPAT64 = _IOR('A', 0x20, struct compat_snd_pcm_status64),
SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64 = _IOWR('A', 0x24, struct compat_snd_pcm_status64),
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
};
static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -531,10 +531,10 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
case __SNDRV_PCM_IOCTL_SYNC_PTR32:
return snd_pcm_common_ioctl(file, substream, cmd, argp);
case __SNDRV_PCM_IOCTL_SYNC_PTR64:
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
if (in_x32_syscall())
return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
return snd_pcm_common_ioctl(file, substream, cmd, argp);
case SNDRV_PCM_IOCTL_HW_REFINE32:
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
@@ -566,10 +566,10 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
return snd_pcm_status_user_compat64(substream, argp, false);
case SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64:
return snd_pcm_status_user_compat64(substream, argp, true);
-#ifdef CONFIG_X86_X32
+#ifdef CONFIG_X86_X32_ABI
case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
return snd_pcm_ioctl_channel_info_x32(substream, argp);
-#endif /* CONFIG_X86_X32 */
+#endif /* CONFIG_X86_X32_ABI */
}
return -ENOIOCTLCMD;
--
2.27.0
3
5
broadwell-rt286, bdw-rt5677: detect card when using Catpt driver
by GitHub pull_request - opened 27 Feb '21
by GitHub pull_request - opened 27 Feb '21
27 Feb '21
alsa-project/alsa-ucm-conf pull request #85 was opened from dpward:
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1933229
Request URL : https://github.com/alsa-project/alsa-ucm-conf/pull/85
Patch URL : https://github.com/alsa-project/alsa-ucm-conf/pull/85.patch
Repository URL: https://github.com/alsa-project/alsa-ucm-conf
1
0
Some USB audio firmware seem to report broken dB values for the volume
controls, and this screws up applications like PulseAudio who blindly
trusts the given data. For example, Edifier G2000 reports a PCM
volume from -128dB to -127dB, and this results in barely inaudible
sound.
This patch adds a sort of sanity check at parsing the dB values in
USB-audio driver and disables the dB reporting if the range looks
bogus. Here, we assume -96dB as the bottom line of the max dB.
Note that, if one can figure out that proper dB range later, it can be
patched in the mixer maps.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211929
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
---
sound/usb/mixer.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index b1c78db0d470..b004b2e63a5d 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1307,6 +1307,17 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
/* totally crap, return an error */
return -EINVAL;
}
+ } else {
+ /* if the max volume is too low, it's likely a bogus range;
+ * here we use -96dB as the threshold
+ */
+ if (cval->dBmax <= -9600) {
+ usb_audio_info(cval->head.mixer->chip,
+ "%d:%d: bogus dB values (%d/%d), disabling dB reporting\n",
+ cval->head.id, mixer_ctrl_intf(cval->head.mixer),
+ cval->dBmin, cval->dBmax);
+ cval->dBmin = cval->dBmax = 0;
+ }
}
return 0;
--
2.26.2
1
0
[PATCH] alsa-tools/hdspmixer: enhance preset save and add hardware ouput loopback buttons
by fassl 27 Feb '21
by fassl 27 Feb '21
27 Feb '21
>From 3c887b31fa57ca3004c2eaf0ee5abc0b3f94da70 Mon Sep 17 00:00:00 2001
From: Jasmin Fazlic <superfassl(a)gmail.com>
Date: Thu, 4 Feb 2021 15:58:33 +0100
Subject: [PATCH 1/2] alsa-tools/hdspmixer: enhance saving of presets
Changing the version in the file header would make
a preset file not readable by older versions of the
tool. If we just append new data always at the end
of the save procedure we should have no problems
reading them with different versions, as they all
just read to a certain point and ignore the rest
of the file.
This patch implements the logic to save the presets
first to a file called file_name.tmp and appends any
extra data that would come after in a possibly present
file_name file.
Any data written by newer versions would remain in
the preset file and from now on no old version should
remove data written by newer versions.
Also since we write to a temporary file and rename
afterwards an extra feature is gained of not corrupting
the preset should we crash.
Signed-off-by: Jasmin Fazlic <superfassl(a)gmail.com>
---
hdspmixer/src/HDSPMixerWindow.cxx | 98 ++++++++++++++++++++-----------
1 file changed, 64 insertions(+), 34 deletions(-)
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx
index 9efc25d..3b3d668 100644
--- a/hdspmixer/src/HDSPMixerWindow.cxx
+++ b/hdspmixer/src/HDSPMixerWindow.cxx
@@ -353,18 +353,25 @@ void HDSPMixerWindow::save()
sizeof(inputs->strips[0]->data[0][0][0]->fader_pos) /
sizeof(inputs->strips[0]->data[0][0][0]->fader_pos[0]));
-
- FILE *file;
-
- if ((file = fopen(file_name, "w")) == NULL) {
- fl_alert("Error opening file %s for saving", file_name);
+ FILE *in,*out;
+
+ /* We want to append any existing extra data that might got written by a
+ * newer version to this file, therefore write our data to file_name.tmp
+ * and append the old data. Also this way we would not corrupt the file
+ * should we crash.
+ */
+ std::string const tmp = file_name + std::string(".tmp");
+ char const * const tmpc = tmp.c_str();
+
+ if ((out = fopen(tmpc, "w")) == NULL) {
+ fl_alert("Error opening file %s for saving", tmpc);
}
if (dirty) {
inputs->buttons->presets->save_preset(current_preset+1);
}
/* since hdspmixer 1.11, we also store the meter level settings. Indicate
* the new on-disk structure via a small header */
- if (fwrite((void *)&header, sizeof(char), sizeof(header), file) !=
+ if (fwrite((void *)&header, sizeof(char), sizeof(header), out) !=
sizeof(header)) {
goto save_error;
}
@@ -374,99 +381,122 @@ void HDSPMixerWindow::save()
for (int preset = 0; preset < 8; ++preset) {
for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) {
/* inputs pans and volumes */
- if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) {
+ if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) {
goto save_error;
}
- if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) {
+ if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) {
goto save_error;
}
/* playbacks pans and volumes */
- if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) {
+ if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) {
goto save_error;
}
- if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) {
+ if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) {
goto save_error;
}
/* inputs mute/solo/dest */
- if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, out) != 1) {
goto save_error;
}
/* playbacks mute/solo/dest */
- if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, out) != 1) {
goto save_error;
}
/* outputs volumes */
- if (fwrite((void *)&(outputs->strips[channel]->data[card][speed][preset]->fader_pos), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(outputs->strips[channel]->data[card][speed][preset]->fader_pos), sizeof(int), 1, out) != 1) {
goto save_error;
}
}
/* Lineouts */
- if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS]->data[card][speed][preset]->fader_pos), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS]->data[card][speed][preset]->fader_pos), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS+1]->data[card][speed][preset]->fader_pos), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS+1]->data[card][speed][preset]->fader_pos), sizeof(int), 1, out) != 1) {
goto save_error;
}
/* Global settings */
- if (fwrite((void *)&(data[card][speed][preset]->input), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->input), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->output), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->output), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->playback), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->playback), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->submix), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->submix), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->submix_value), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->submix_value), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->solo), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->solo), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->mute), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->mute), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->last_destination), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->last_destination), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->rmsplus3), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->rmsplus3), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->numbers), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->numbers), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->over), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->over), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->level), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->level), sizeof(int), 1, out) != 1) {
goto save_error;
}
- if (fwrite((void *)&(data[card][speed][preset]->rate), sizeof(int), 1, file) != 1) {
+ if (fwrite((void *)&(data[card][speed][preset]->rate), sizeof(int), 1, out) != 1) {
goto save_error;
}
}
}
}
- fclose(file);
+
+ /* If the file we want to write already exists it could be possible that it
+ * was saved with a newer version. If that is the case we just append its
+ * content to the new output file and that way ensure that we don't lose any
+ * data the new version wrote.
+ */
+ if ((in = fopen(file_name, "r")) != NULL) {
+ if (!fseek(in, ftell(out), SEEK_SET)) {
+ char buff[512];
+ size_t read;
+ while ((read = fread(&buff, sizeof(char), sizeof(buff), in)) != 0)
+ fwrite(buff, sizeof(char), read, out);
+ if (ferror(in) || ferror(out))
+ fl_alert("Error appending %s to %s", file_name, tmpc);
+ }
+ fclose(in);
+ }
+
+ fclose(out);
+
+ if (rename(tmpc, file_name))
+ fl_alert("Error renaming %s to %s", tmpc, file_name);
+ ::remove(tmpc);
+
return;
save_error:
- fclose(file);
+ fclose(out);
fl_alert("Error saving presets to file %s", file_name);
return;
}
--
2.27.0
>From 2dbf462a9126da817db40f4d62207b47e245f3e7 Mon Sep 17 00:00:00 2001
From: Jasmin Fazlic <superfassl(a)gmail.com>
Date: Thu, 4 Feb 2021 17:00:22 +0100
Subject: [PATCH 2/2] alsa-tools/hdspmixer: add output loopback buttons
This patch adds "LPBK" buttons to the output strip
channels allowing to toggle the hardware output
loopback state.
Efforts were made to hide the buttons for not yet
enabled devices but due to difficulties in implementation
was cancelled for the time being. Should it be a no-go
efforts should be made to fix this and hide them,
although I would think fixing the driver for other
devices would be an effort with much more merit.
This is currently only enabled for HDSP9632 devices
with following driver patch:
https://github.com/tiwai/sound/commit/da2a040ee7cfe1dd57d5bec7906cb979c5787…
Signed-off-by: Jasmin Fazlic <superfassl(a)gmail.com>
---
hdspmixer/pixmaps/loopback.xpm | 69 ++++
hdspmixer/pixmaps/output.xpm | 498 +++++++++++++++-----------
hdspmixer/pixmaps/output_r.xpm | 498 +++++++++++++++-----------
hdspmixer/src/HDSPMixerCard.cxx | 34 ++
hdspmixer/src/HDSPMixerCard.h | 2 +
hdspmixer/src/HDSPMixerLoopback.cxx | 133 +++++++
hdspmixer/src/HDSPMixerLoopback.h | 48 +++
hdspmixer/src/HDSPMixerOutput.cxx | 1 +
hdspmixer/src/HDSPMixerOutput.h | 3 +
hdspmixer/src/HDSPMixerOutputData.h | 1 +
hdspmixer/src/HDSPMixerOutputs.cxx | 4 +-
hdspmixer/src/HDSPMixerPresetData.cxx | 1 +
hdspmixer/src/HDSPMixerPresetData.h | 1 +
hdspmixer/src/HDSPMixerPresets.cxx | 2 +
hdspmixer/src/HDSPMixerWindow.cxx | 68 ++++
hdspmixer/src/Makefile.am | 2 +
hdspmixer/src/defines.h | 2 +-
hdspmixer/src/pixmaps.cxx | 1 +
hdspmixer/src/pixmaps.h | 1 +
19 files changed, 931 insertions(+), 438 deletions(-)
create mode 100644 hdspmixer/pixmaps/loopback.xpm
create mode 100644 hdspmixer/src/HDSPMixerLoopback.cxx
create mode 100644 hdspmixer/src/HDSPMixerLoopback.h
diff --git a/hdspmixer/pixmaps/loopback.xpm b/hdspmixer/pixmaps/loopback.xpm
new file mode 100644
index 0000000..a327467
--- /dev/null
+++ b/hdspmixer/pixmaps/loopback.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+char const * loopback_xpm[] = {
+"34 15 51 1",
+" c None",
+". c #2E3038",
+"+ c #FFFB7C",
+"@ c #FDF97B",
+"# c #2E2D11",
+"$ c #000000",
+"% c #383716",
+"& c #898740",
+"* c #F1EE75",
+"= c #22210A",
+"- c #727034",
+"; c #E2DE6D",
+"> c #D5D267",
+", c #787637",
+"' c #FBF77A",
+") c #AAA750",
+"! c #ABA851",
+"~ c #CDC962",
+"{ c #83813C",
+"] c #C8C560",
+"^ c #84823D",
+"/ c #F7F378",
+"( c #949145",
+"_ c #B7B457",
+": c #949245",
+"< c #353414",
+"[ c #87853F",
+"} c #F1ED75",
+"| c #3B3A17",
+"1 c #DFDB6C",
+"2 c #161505",
+"3 c #4B4A20",
+"4 c #E5E16E",
+"5 c #FEFA7C",
+"6 c #E8E470",
+"7 c #535124",
+"8 c #FAF679",
+"9 c #E7E370",
+"0 c #66642E",
+"a c #E4E06E",
+"b c #F6F277",
+"c c #EAE671",
+"d c #E0DC6C",
+"e c #B9B658",
+"f c #5F5D2A",
+"g c #EDE973",
+"h c #69672F",
+"i c #DDD96A",
+"j c #333342",
+"k c #32323E",
+"l c #313136",
+"..................................",
+".++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++.",
+".+++@#++++@$$%&*@$$=-;+@#++>,*+++.",
+".+++@#++++@#+')!@#+@~{+@#+]^/++++.",
+".+++@#++++@#+'!!@#+@~(+@#_:'+++++.",
+".+++@#++++@$$<[}@$$$|1+@234++++++.",
+".+++@#++++@#++++@#+5678@#90a+++++.",
+".+++@#++++@#++++@#+59#b@#+c0d++++.",
+".+++@$$$$e@#++++@$$2f]+@#++ghi+++.",
+".++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++.",
+"..jklllllllllkj....jklllllllllkj.."};
diff --git a/hdspmixer/pixmaps/output.xpm b/hdspmixer/pixmaps/output.xpm
index 8f7cd65..c827b1c 100644
--- a/hdspmixer/pixmaps/output.xpm
+++ b/hdspmixer/pixmaps/output.xpm
@@ -1,220 +1,282 @@
/* XPM */
char const * output_xpm[] = {
-"36 208 9 1",
-" c #595966",
-". c #2E3038",
-"+ c #000000",
-"@ c #474951",
-"# c #404044",
-"$ c #7A7A8F",
-"% c #27272B",
-"& c #616176",
-"* c #737384",
-" ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..................++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ..................++++++++++...... ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" "};
+"36 224 55 1",
+" c None",
+". c #595966",
+"+ c #2E3038",
+"@ c #000000",
+"# c #474951",
+"$ c #404044",
+"% c #7A7A8F",
+"& c #27272B",
+"* c #616176",
+"= c #737384",
+"- c #757585",
+"; c #D4D4D4",
+"> c #D6D6D6",
+", c #D3D3D4",
+"' c #C3C3C6",
+") c #848491",
+"! c #D5D5D5",
+"~ c #CACACB",
+"{ c #93939C",
+"] c #9D9DA5",
+"^ c #C8C8CA",
+"/ c #787888",
+"( c #B6B6BA",
+"_ c #A3A3AA",
+": c #C5C5C7",
+"< c #A7A7AE",
+"[ c #C4C4C6",
+"} c #7D7D8C",
+"| c #797989",
+"1 c #C0C0C2",
+"2 c #AFAFB4",
+"3 c #BFBFC2",
+"4 c #D3D3D3",
+"5 c #95959F",
+"6 c #D5D5D6",
+"7 c #D1D1D2",
+"8 c #91919B",
+"9 c #757586",
+"0 c #8E8E99",
+"a c #D1D1D1",
+"b c #8F8F99",
+"c c #CBCBCD",
+"d c #92929C",
+"e c #7F7F8D",
+"f c #8C8C97",
+"g c #96969F",
+"h c #AFAFB5",
+"i c #CECECF",
+"j c #A6A6AD",
+"k c #8A8A96",
+"l c #CCCCCD",
+"m c #9898A1",
+"n c #333342",
+"o c #32323E",
+"p c #313136",
+"....................................",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++++++++++++@@@@@@@@@@++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+"....................................",
+".++++++++++++++++++++++++++++++++++.",
+".+================================+.",
+".+================================+.",
+".+================================+.",
+".+===-;====->>,')->>!~{=-;==]^)===+.",
+".+===-;====-;=/((-;=-_:=-;=<[}====+.",
+".+===-;====-;=|((-;=-_1=-;23/=====+.",
+".+===-;====->>,[)->>>45=-678======+.",
+".+===-;====-;====-;=90a|-;bcd=====+.",
+".+===-;====-;====-;=9b;e-;=fcg====+.",
+".+===->>>>h-;====->>6ij=-;==klm===+.",
+".+================================+.",
+".+================================+.",
+".+================================+.",
+".++nopppppppppon++++nopppppppppon++.",
+"...................................."};
diff --git a/hdspmixer/pixmaps/output_r.xpm b/hdspmixer/pixmaps/output_r.xpm
index ab2ca99..51b1984 100644
--- a/hdspmixer/pixmaps/output_r.xpm
+++ b/hdspmixer/pixmaps/output_r.xpm
@@ -1,220 +1,282 @@
/* XPM */
char const * output_r_xpm[] = {
-"36 208 9 1",
-" c #595966",
-". c #2E3038",
-"+ c #000000",
-"@ c #474951",
-"# c #404044",
-"$ c #7A7A8F",
-"% c #27272B",
-"& c #616176",
-"* c #737384",
-" ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..................++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" .@@@@@@@#$@@@.....++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ........%&........++++++++++...... ",
-" ..................++++++++++...... ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" ..++++++++++++++++++++++++++++++.. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" ..******************************.. ",
-" .................................. ",
-" .................................. ",
-" .................................. ",
-" "};
+"36 224 55 1",
+" c None",
+". c #595966",
+"+ c #2E3038",
+"@ c #000000",
+"# c #474951",
+"$ c #404044",
+"% c #7A7A8F",
+"& c #27272B",
+"* c #616176",
+"= c #737384",
+"- c #757585",
+"; c #D4D4D4",
+"> c #D6D6D6",
+", c #D3D3D4",
+"' c #C3C3C6",
+") c #848491",
+"! c #D5D5D5",
+"~ c #CACACB",
+"{ c #93939C",
+"] c #9D9DA5",
+"^ c #C8C8CA",
+"/ c #787888",
+"( c #B6B6BA",
+"_ c #A3A3AA",
+": c #C5C5C7",
+"< c #A7A7AE",
+"[ c #C4C4C6",
+"} c #7D7D8C",
+"| c #797989",
+"1 c #C0C0C2",
+"2 c #AFAFB4",
+"3 c #BFBFC2",
+"4 c #D3D3D3",
+"5 c #95959F",
+"6 c #D5D5D6",
+"7 c #D1D1D2",
+"8 c #91919B",
+"9 c #757586",
+"0 c #8E8E99",
+"a c #D1D1D1",
+"b c #8F8F99",
+"c c #CBCBCD",
+"d c #92929C",
+"e c #7F7F8D",
+"f c #8C8C97",
+"g c #96969F",
+"h c #AFAFB5",
+"i c #CECECF",
+"j c #A6A6AD",
+"k c #8A8A96",
+"l c #CCCCCD",
+"m c #9898A1",
+"n c #333342",
+"o c #32323E",
+"p c #313136",
+"....................................",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".+#######$%###+++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++&*++++++++@@@@@@@@@@++++++.",
+".++++++++++++++++++@@@@@@@@@@++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++==============================++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++.",
+"....................................",
+".++++++++++++++++++++++++++++++++++.",
+".+================================+.",
+".+================================+.",
+".+================================+.",
+".+===-;====->>,')->>!~{=-;==]^)===+.",
+".+===-;====-;=/((-;=-_:=-;=<[}====+.",
+".+===-;====-;=|((-;=-_1=-;23/=====+.",
+".+===-;====->>,[)->>>45=-678======+.",
+".+===-;====-;====-;=90a|-;bcd=====+.",
+".+===-;====-;====-;=9b;e-;=fcg====+.",
+".+===->>>>h-;====->>6ij=-;==klm===+.",
+".+================================+.",
+".+================================+.",
+".+================================+.",
+".++nopppppppppon++++nopppppppppon++.",
+"...................................."};
diff --git a/hdspmixer/src/HDSPMixerCard.cxx b/hdspmixer/src/HDSPMixerCard.cxx
index ce40ba7..72232c8 100644
--- a/hdspmixer/src/HDSPMixerCard.cxx
+++ b/hdspmixer/src/HDSPMixerCard.cxx
@@ -231,6 +231,8 @@ void HDSPMixerCard::adjustSettings() {
/* should never happen */
break;
}
+
+ max_channels = sizeof(channel_map_mf_ss);
}
if (type == Digiface) {
@@ -253,6 +255,8 @@ void HDSPMixerCard::adjustSettings() {
/* should never happen */
break;
}
+
+ max_channels = sizeof(channel_map_df_ss);
}
if (type == RPM) {
@@ -263,6 +267,8 @@ void HDSPMixerCard::adjustSettings() {
channel_map_input = channel_map_playback = channel_map_rpm;
dest_map = dest_map_rpm;
meter_map_input = meter_map_playback = channel_map_rpm;
+
+ max_channels = sizeof(channel_map_rpm);
}
@@ -286,6 +292,8 @@ void HDSPMixerCard::adjustSettings() {
/* should never happen */
break;
}
+
+ max_channels = sizeof(channel_map_df_ss);
}
if (type == H9632) {
@@ -312,6 +320,8 @@ void HDSPMixerCard::adjustSettings() {
meter_map_input = meter_map_playback = channel_map_h9632_qs;
break;
}
+
+ max_channels = sizeof(channel_map_h9632_ss);
}
if (HDSPeMADI == type) {
@@ -341,6 +351,7 @@ void HDSPMixerCard::adjustSettings() {
break;
}
+ max_channels = sizeof(channel_map_unity_ss);
}
if (HDSPeAIO == type) {
@@ -379,6 +390,7 @@ void HDSPMixerCard::adjustSettings() {
break;
}
+ max_channels = sizeof(channel_map_aio_out_ss);
}
if (HDSP_AES == type) {
@@ -394,6 +406,7 @@ void HDSPMixerCard::adjustSettings() {
meter_map_input = channel_map_aes32;
meter_map_playback = channel_map_aes32;
+ max_channels = sizeof(channel_map_aes32);
}
if (HDSPeRayDAT == type) {
@@ -426,6 +439,7 @@ void HDSPMixerCard::adjustSettings() {
break;
}
+ max_channels = sizeof(channel_map_raydat_ss);
}
window_width = (channels_playback+2)*STRIP_WIDTH;
@@ -545,3 +559,23 @@ int HDSPMixerCard::initializeCard(HDSPMixerWindow *w)
return 0;
}
+int HDSPMixerCard::supportsLoopback() const
+{
+ int err = 0;
+ snd_ctl_elem_value_t *elemval;
+ snd_ctl_elem_id_t * elemid;
+ snd_ctl_t *handle;
+ snd_ctl_elem_value_alloca(&elemval);
+ snd_ctl_elem_id_alloca(&elemid);
+ if ((err = snd_ctl_open(&handle, name, SND_CTL_NONBLOCK)) < 0)
+ return err;
+
+ snd_ctl_elem_id_set_name(elemid, "Output Loopback");
+ snd_ctl_elem_id_set_interface(elemid, SND_CTL_ELEM_IFACE_HWDEP);
+ snd_ctl_elem_id_set_index(elemid, 0);
+ snd_ctl_elem_value_set_id(elemval, elemid);
+ err = snd_ctl_elem_read(handle, elemval);
+ snd_ctl_close(handle);
+
+ return err;
+}
diff --git a/hdspmixer/src/HDSPMixerCard.h b/hdspmixer/src/HDSPMixerCard.h
index faaeefa..eecfca3 100644
--- a/hdspmixer/src/HDSPMixerCard.h
+++ b/hdspmixer/src/HDSPMixerCard.h
@@ -52,6 +52,7 @@ public:
HDSPMixerCard(int cardtype, int id, char *shortname);
int channels_input, channels_playback, window_width, window_height, card_id;
int channels_output;
+ int max_channels;
int type;
int last_preset; /* Last activated preset before switching to another card */
int last_dirty; /* Last dirty flag before switching to another card */
@@ -68,6 +69,7 @@ public:
void adjustSettings();
void getAeb();
hdsp_9632_aeb_t h9632_aeb;
+ int supportsLoopback() const;
};
#endif
diff --git a/hdspmixer/src/HDSPMixerLoopback.cxx b/hdspmixer/src/HDSPMixerLoopback.cxx
new file mode 100644
index 0000000..fcfec2a
--- /dev/null
+++ b/hdspmixer/src/HDSPMixerLoopback.cxx
@@ -0,0 +1,133 @@
+/*
+ * HDSPMixer
+ *
+ * Copyright (C) 2003 Thomas Charbonnel (thomas(a)undata.org)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#pragma implementation
+#include "HDSPMixerLoopback.h"
+
+HDSPMixerLoopback::HDSPMixerLoopback(int x, int y, int idx):Fl_Widget(x, y, 34, 15)
+{
+ basew = (HDSPMixerWindow *)window();
+ index = idx;
+}
+
+void HDSPMixerLoopback::draw()
+{
+ if (_loopback == 1)
+ fl_draw_pixmap(loopback_xpm, x(), y());
+}
+
+int HDSPMixerLoopback::get()
+{
+ auto const card { basew->cards[basew->current_card] };
+
+ if (card->supportsLoopback() != 0)
+ return -1;
+
+ if (index >= card->max_channels)
+ return -1;
+
+ int err;
+ snd_ctl_elem_value_t *elemval;
+ snd_ctl_elem_id_t * elemid;
+ snd_ctl_t *handle;
+ snd_ctl_elem_value_alloca(&elemval);
+ snd_ctl_elem_id_alloca(&elemid);
+ char const * const name = basew->cards[basew->current_card]->name;
+ if ((err = snd_ctl_open(&handle, name, SND_CTL_NONBLOCK)) < 0) {
+ fprintf(stderr, "Error accessing ctl interface on card %s\n.", name);
+ return -1;
+ }
+
+ snd_ctl_elem_id_set_name(elemid, "Output Loopback");
+ snd_ctl_elem_id_set_interface(elemid, SND_CTL_ELEM_IFACE_HWDEP);
+ snd_ctl_elem_id_set_index(elemid, index);
+ snd_ctl_elem_value_set_id(elemval, elemid);
+ if ((err = snd_ctl_elem_read(handle, elemval)) < 0)
+ fprintf(stderr, "cannot read loopback: %d\n", err);
+ else
+ _loopback = snd_ctl_elem_value_get_integer(elemval, 0);
+
+ snd_ctl_close(handle);
+
+ return _loopback;
+}
+
+void HDSPMixerLoopback::set(int l)
+{
+ auto const card { basew->cards[basew->current_card] };
+
+ if (card->supportsLoopback() != 0)
+ return;
+
+ if (index >= card->max_channels)
+ return;
+
+ if (l != _loopback) {
+ int err;
+
+ snd_ctl_elem_id_t *id;
+ snd_ctl_elem_value_t *ctl;
+ snd_ctl_t *handle;
+
+ snd_ctl_elem_value_alloca(&ctl);
+ snd_ctl_elem_id_alloca(&id);
+ snd_ctl_elem_id_set_name(id, "Output Loopback");
+ snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_HWDEP);
+ snd_ctl_elem_id_set_device(id, 0);
+ snd_ctl_elem_id_set_index(id, index);
+ snd_ctl_elem_value_set_id(ctl, id);
+
+ if ((err = snd_ctl_open(
+ &handle, basew->cards[basew->current_card]->name, SND_CTL_NONBLOCK)) < 0) {
+ fprintf(stderr, "Alsa error 1: %s\n", snd_strerror(err));
+ return;
+ }
+
+ snd_ctl_elem_value_set_integer(ctl, 0, l);
+ if ((err = snd_ctl_elem_write(handle, ctl)) < 0) {
+ fprintf(stderr, "Alsa error 2: %s\n", snd_strerror(err));
+ snd_ctl_close(handle);
+ return;
+ }
+
+ _loopback = l;
+
+ snd_ctl_close(handle);
+
+ redraw();
+ }
+}
+
+int HDSPMixerLoopback::handle(int e)
+{
+ int button3 = Fl::event_button3();
+ switch (e) {
+ case FL_PUSH:
+ set(!_loopback);
+ if (button3)
+ relative->set(_loopback);
+ basew->checkState();
+ redraw();
+ return 1;
+ default:
+ return Fl_Widget::handle(e);
+ }
+}
+
diff --git a/hdspmixer/src/HDSPMixerLoopback.h b/hdspmixer/src/HDSPMixerLoopback.h
new file mode 100644
index 0000000..07f1f0c
--- /dev/null
+++ b/hdspmixer/src/HDSPMixerLoopback.h
@@ -0,0 +1,48 @@
+/*
+ * HDSPMixer
+ *
+ * Copyright (C) 2003 Thomas Charbonnel (thomas(a)undata.org)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#pragma interface
+#ifndef HDSPMixerLoopback_H
+#define HDSPMixerLoopback_H
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include "HDSPMixerWindow.h"
+#include "pixmaps.h"
+
+class HDSPMixerWindow;
+
+class HDSPMixerLoopback:public Fl_Widget
+{
+private:
+ HDSPMixerWindow *basew;
+ int _loopback{-1};
+public:
+ HDSPMixerLoopback *relative;
+ int index;
+ HDSPMixerLoopback(int x, int y, int idx);
+ void draw();
+ int handle(int e);
+ int get();
+ void set(int l);
+};
+
+#endif
+
diff --git a/hdspmixer/src/HDSPMixerOutput.cxx b/hdspmixer/src/HDSPMixerOutput.cxx
index 0053fe0..7f80a74 100644
--- a/hdspmixer/src/HDSPMixerOutput.cxx
+++ b/hdspmixer/src/HDSPMixerOutput.cxx
@@ -204,6 +204,7 @@ HDSPMixerOutput::HDSPMixerOutput(int x, int y, int w, int h, int num):Fl_Group(x
peak = new HDSPMixerPeak(x+3, y+4, 0);
gain = new HDSPMixerGain(x+3, y+175, 0);
meter = new HDSPMixerMeter(x+20, y+27, false, peak);
+ loopback = new HDSPMixerLoopback(x+1, y+208, out_num);
end();
}
diff --git a/hdspmixer/src/HDSPMixerOutput.h b/hdspmixer/src/HDSPMixerOutput.h
index 6278cfd..1e04ae5 100644
--- a/hdspmixer/src/HDSPMixerOutput.h
+++ b/hdspmixer/src/HDSPMixerOutput.h
@@ -27,6 +27,7 @@
#include <FL/fl_draw.H>
#include <alsa/sound/hdsp.h>
#include "HDSPMixerFader.h"
+#include "HDSPMixerLoopback.h"
#include "HDSPMixerPeak.h"
#include "HDSPMixerGain.h"
#include "HDSPMixerMeter.h"
@@ -36,6 +37,7 @@
class HDSPMixerFader;
class HDSPMixerGain;
+class HDSPMixerLoopback;
class HDSPMixerPeak;
class HDSPMixerMeter;
class HDSPMixerOutputData;
@@ -56,6 +58,7 @@ public:
HDSPMixerFader *fader;
HDSPMixerGain *gain;
HDSPMixerMeter *meter;
+ HDSPMixerLoopback *loopback;
HDSPMixerOutput(int x, int y, int w, int h, int out);
void draw();
void draw_background();
diff --git a/hdspmixer/src/HDSPMixerOutputData.h b/hdspmixer/src/HDSPMixerOutputData.h
index 885047b..75b9109 100644
--- a/hdspmixer/src/HDSPMixerOutputData.h
+++ b/hdspmixer/src/HDSPMixerOutputData.h
@@ -26,6 +26,7 @@ class HDSPMixerOutputData
{
public:
int fader_pos;
+ int loopback;
HDSPMixerOutputData();
};
diff --git a/hdspmixer/src/HDSPMixerOutputs.cxx b/hdspmixer/src/HDSPMixerOutputs.cxx
index 0b4e7f4..342685d 100644
--- a/hdspmixer/src/HDSPMixerOutputs.cxx
+++ b/hdspmixer/src/HDSPMixerOutputs.cxx
@@ -25,13 +25,15 @@ HDSPMixerOutputs::HDSPMixerOutputs(int x, int y, int w, int h, int nchans):Fl_Gr
{
int i;
for (i = 0; i < HDSP_MAX_CHANNELS+2; i += 2) {
- strips[i] = new HDSPMixerOutput((i*STRIP_WIDTH), y, STRIP_WIDTH, SMALLSTRIP_HEIGHT, i);
+ strips[i] = new HDSPMixerOutput((i*STRIP_WIDTH), y, STRIP_WIDTH, SMALLSTRIP_HEIGHT, i);
strips[i+1] = new HDSPMixerOutput(((i+1)*STRIP_WIDTH), y, STRIP_WIDTH, SMALLSTRIP_HEIGHT, i+1);
/* Setup linked stereo channels */
strips[i]->fader->relative = strips[i+1]->fader;
strips[i+1]->fader->relative = strips[i]->fader;
strips[i]->fader->gain = strips[i]->gain;
strips[i+1]->fader->gain = strips[i+1]->gain;
+ strips[i]->loopback->relative = strips[i+1]->loopback;
+ strips[i+1]->loopback->relative = strips[i]->loopback;
}
empty_aebo[0] = new HDSPMixerEmpty((nchans-6)*STRIP_WIDTH, y, 2*STRIP_WIDTH, SMALLSTRIP_HEIGHT, 0);
diff --git a/hdspmixer/src/HDSPMixerPresetData.cxx b/hdspmixer/src/HDSPMixerPresetData.cxx
index 276d101..6359732 100644
--- a/hdspmixer/src/HDSPMixerPresetData.cxx
+++ b/hdspmixer/src/HDSPMixerPresetData.cxx
@@ -36,5 +36,6 @@ HDSPMixerPresetData::HDSPMixerPresetData()
over = 3;
level = 0;
rate = 1;
+ loopback = 0;
}
diff --git a/hdspmixer/src/HDSPMixerPresetData.h b/hdspmixer/src/HDSPMixerPresetData.h
index 58536d3..3b46b92 100644
--- a/hdspmixer/src/HDSPMixerPresetData.h
+++ b/hdspmixer/src/HDSPMixerPresetData.h
@@ -38,6 +38,7 @@ public:
int over;
int rate;
int rmsplus3;
+ int loopback;
HDSPMixerPresetData();
};
diff --git a/hdspmixer/src/HDSPMixerPresets.cxx b/hdspmixer/src/HDSPMixerPresets.cxx
index aeeb9c9..82654d9 100644
--- a/hdspmixer/src/HDSPMixerPresets.cxx
+++ b/hdspmixer/src/HDSPMixerPresets.cxx
@@ -143,6 +143,7 @@ void HDSPMixerPresets::save_preset(int prst) {
basew->playbacks->strips[i]->data[card][speed][p]->dest = basew->playbacks->strips[i]->targets->selected;
basew->outputs->strips[i]->data[card][speed][p]->fader_pos = basew->outputs->strips[i]->fader->pos[0];
+ basew->outputs->strips[i]->data[card][speed][p]->loopback = basew->outputs->strips[i]->loopback->get();
}
/* Line outs */
basew->outputs->strips[HDSP_MAX_CHANNELS]->data[card][speed][p]->fader_pos = basew->outputs->strips[HDSP_MAX_CHANNELS]->fader->pos[0];
@@ -188,6 +189,7 @@ void HDSPMixerPresets::restore_preset(int prst) {
basew->playbacks->strips[i]->targets->selected = basew->playbacks->strips[i]->data[card][speed][p]->dest;
basew->outputs->strips[i]->fader->pos[0] = basew->outputs->strips[i]->data[card][speed][p]->fader_pos;
+ basew->outputs->strips[i]->loopback->set(basew->outputs->strips[i]->data[card][speed][p]->loopback);
}
/* Line outs */
basew->outputs->strips[HDSP_MAX_CHANNELS]->fader->pos[0] = basew->outputs->strips[HDSP_MAX_CHANNELS+1]->data[card][speed][p]->fader_pos;
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx
index 3b3d668..4a911c1 100644
--- a/hdspmixer/src/HDSPMixerWindow.cxx
+++ b/hdspmixer/src/HDSPMixerWindow.cxx
@@ -471,6 +471,29 @@ void HDSPMixerWindow::save()
}
}
+ /* Output loopback data */
+ for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) {
+ auto const strip = outputs->strips[channel];
+
+ for (int card = 0; card < MAX_CARDS; ++card) {
+ auto const data = strip->data[card];
+
+ for (int speed = 0; speed < 3; ++speed) {
+ auto const spd = data[speed];
+
+ for (int preset = 0; preset < 8; ++preset) {
+ auto const data = spd[preset];
+
+ if (fwrite((void *)&(data->loopback),
+ sizeof(int),
+ 1,
+ out) != 1)
+ goto save_error;
+ }
+ }
+ }
+ }
+
/* If the file we want to write already exists it could be possible that it
* was saved with a newer version. If that is the case we just append its
* content to the new output file and that way ensure that we don't lose any
@@ -519,6 +542,7 @@ void HDSPMixerWindow::load()
bool ondisk_v1 = false;
int pan_array_size = 14; /* old (pre 1.0.24) HDSP_MAX_DEST */
int channels_per_card = 26; /* old (pre 1.0.24) HDSP_MAX_CHANNELS */
+ bool res = true;
if (fread(&buffer, sizeof(char), sizeof(buffer), file) != sizeof(buffer)) {
goto load_error;
@@ -647,6 +671,46 @@ void HDSPMixerWindow::load()
}
}
}
+
+ /* Output loopback data */
+ for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) {
+ auto const strip = outputs->strips[channel];
+
+ for (int card = 0; card < MAX_CARDS; ++card) {
+ auto const data = strip->data[card];
+
+ for (int speed = 0; speed < 3; ++speed) {
+ auto const spd = data[speed];
+
+ for (int preset = 0; preset < 8; ++preset) {
+ auto const data = spd[preset];
+
+ /* TODO: Somewhere we get a value of 5 from, investigate
+ * this another day. For now just reset it here and
+ * continue looping to reset the value.
+ */
+ data->loopback = 0;
+
+ if (feof(file)) {
+ res = true;
+ continue;
+ }
+
+ if (ferror(file)) {
+ res = false;
+ continue;
+ }
+
+ if (fread((void *)&(data->loopback), sizeof(int), 1, file) != 1)
+ res = false;
+ }
+ }
+ }
+ }
+
+ if (!res)
+ goto load_error;
+
fclose(file);
setTitleWithFilename();
resetMixer();
@@ -844,6 +908,8 @@ void HDSPMixerWindow::restoreDefaults(int card)
}
outputs->strips[i]->data[card][speed][preset]->fader_pos = (preset != 4) ? 137*CF : 0;
outputs->strips[i+1]->data[card][speed][preset]->fader_pos = (preset != 4) ? 137*CF : 0;
+ outputs->strips[i]->data[card][speed][preset]->loopback = 0;
+ outputs->strips[i+1]->data[card][speed][preset]->loopback = 0;
if (preset == 3 || preset == 7) {
inputs->strips[i]->data[card][speed][preset]->mute = 1;
inputs->strips[i+1]->data[card][speed][preset]->mute = 1;
@@ -1051,6 +1117,8 @@ void HDSPMixerWindow::checkState()
/* Outputs row */
if (outputs->strips[i]->data[current_card][speed][p]->fader_pos != outputs->strips[i]->fader->pos[0])
corrupt++;
+ if (outputs->strips[i]->data[current_card][speed][p]->loopback != outputs->strips[i]->loopback->get())
+ corrupt++;
}
/* Global settings */
diff --git a/hdspmixer/src/Makefile.am b/hdspmixer/src/Makefile.am
index e80a8ac..ebc4c3c 100644
--- a/hdspmixer/src/Makefile.am
+++ b/hdspmixer/src/Makefile.am
@@ -15,6 +15,8 @@ hdspmixer_SOURCES = \
HDSPMixerEmpty.h \
HDSPMixerOutput.cxx \
HDSPMixerOutput.h \
+ HDSPMixerLoopback.cxx \
+ HDSPMixerLoopback.h \
HDSPMixerIOMixer.cxx \
HDSPMixerIOMixer.h \
HDSPMixerSelector.cxx \
diff --git a/hdspmixer/src/defines.h b/hdspmixer/src/defines.h
index af5c382..e76141b 100644
--- a/hdspmixer/src/defines.h
+++ b/hdspmixer/src/defines.h
@@ -34,7 +34,7 @@
#define STRIP_WIDTH 36
#define FULLSTRIP_HEIGHT 253
-#define SMALLSTRIP_HEIGHT 208
+#define SMALLSTRIP_HEIGHT 224
#define MENU_HEIGHT 20
#define MIN_WIDTH 2*STRIP_WIDTH
diff --git a/hdspmixer/src/pixmaps.cxx b/hdspmixer/src/pixmaps.cxx
index 2f7c589..34f8834 100644
--- a/hdspmixer/src/pixmaps.cxx
+++ b/hdspmixer/src/pixmaps.cxx
@@ -47,6 +47,7 @@
#include "../pixmaps/over.xpm"
#include "../pixmaps/peak.xpm"
#include "../pixmaps/solo.xpm"
+#include "../pixmaps/loopback.xpm"
#include "../pixmaps/iomixer_r.xpm"
#include "../pixmaps/output_r.xpm"
#include "../pixmaps/matrix_black.xpm"
diff --git a/hdspmixer/src/pixmaps.h b/hdspmixer/src/pixmaps.h
index b980a62..3548ba3 100644
--- a/hdspmixer/src/pixmaps.h
+++ b/hdspmixer/src/pixmaps.h
@@ -49,6 +49,7 @@ extern char const * output_xpm[];
extern char const * over_xpm[];
extern char const * peak_xpm[];
extern char const * solo_xpm[];
+extern char const * loopback_xpm[];
extern char const * iomixer_r_xpm[];
extern char const * output_r_xpm[];
extern char const * matrix_white_xpm[];
--
2.27.0
3
5
27 Feb '21
The commit 93db51d06b32 ("ALSA: usb-audio: Check valid altsetting at
parsing rates for UAC2/3") changed the behavior of the function
set_sample_rate_v2v3() slightly to treat the inconsistent sample rate
as an error. It was done by assumption that the sample rate
validation should have been done at the parser phase as implemented in
that patch. But the validation is later selectively enabled only for
certain devices as it causes a regression (the commit fe773b8711e3
"ALSA: usb-audio: workaround for iface reset issue"), and now the
inconsistency surfaced as a fatal error while it worked in the past as
is, as reported for FiiO M3K DAC.
For recovering from the regression, change set_sample_rate_v2v3()
again to ignore the sample rate difference as non-error.
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1182633
Fixes: 93db51d06b32 ("ALSA: usb-audio: Check valid altsetting at parsing rates for UAC2/3")
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
---
sound/usb/clock.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 8243652d5604..a746802d0ac3 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -652,10 +652,10 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip,
cur_rate = prev_rate;
if (cur_rate != rate) {
- usb_audio_warn(chip,
- "%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n",
- fmt->iface, fmt->altsetting, rate, cur_rate);
- return -ENXIO;
+ usb_audio_dbg(chip,
+ "%d:%d: freq mismatch: req %d, clock runs @%d\n",
+ fmt->iface, fmt->altsetting, rate, cur_rate);
+ /* continue processing */
}
validation:
--
2.26.2
1
0
This series implements a driver part of the virtio sound device
specification v8 [1].
The driver supports PCM playback and capture substreams, jack and
channel map controls. A message-based transport is used to write/read
PCM frames to/from a device.
As a device part was used OpenSynergy proprietary implementation.
v5 changes:
- Fixed another bunch of sparse warnings
(replaced virtio_cread() -> virtio_cread_le()), no functional changes.
(Sorry, I didn't know how to run sparse locally, now everything should be fixed)
[1] https://lists.oasis-open.org/archives/virtio-dev/202003/msg00185.html
Anton Yakovlev (9):
uapi: virtio_ids: add a sound device type ID from OASIS spec
ALSA: virtio: add virtio sound driver
ALSA: virtio: handling control messages
ALSA: virtio: build PCM devices and substream hardware descriptors
ALSA: virtio: handling control and I/O messages for the PCM device
ALSA: virtio: PCM substream operators
ALSA: virtio: introduce jack support
ALSA: virtio: introduce PCM channel map support
ALSA: virtio: introduce device suspend/resume support
MAINTAINERS | 9 +
include/uapi/linux/virtio_ids.h | 1 +
include/uapi/linux/virtio_snd.h | 334 +++++++++++++++++++++
sound/Kconfig | 2 +
sound/Makefile | 3 +-
sound/virtio/Kconfig | 10 +
sound/virtio/Makefile | 13 +
sound/virtio/virtio_card.c | 462 +++++++++++++++++++++++++++++
sound/virtio/virtio_card.h | 113 ++++++++
sound/virtio/virtio_chmap.c | 219 ++++++++++++++
sound/virtio/virtio_ctl_msg.c | 310 ++++++++++++++++++++
sound/virtio/virtio_ctl_msg.h | 78 +++++
sound/virtio/virtio_jack.c | 233 +++++++++++++++
sound/virtio/virtio_pcm.c | 498 ++++++++++++++++++++++++++++++++
sound/virtio/virtio_pcm.h | 120 ++++++++
sound/virtio/virtio_pcm_msg.c | 392 +++++++++++++++++++++++++
sound/virtio/virtio_pcm_ops.c | 491 +++++++++++++++++++++++++++++++
17 files changed, 3287 insertions(+), 1 deletion(-)
create mode 100644 include/uapi/linux/virtio_snd.h
create mode 100644 sound/virtio/Kconfig
create mode 100644 sound/virtio/Makefile
create mode 100644 sound/virtio/virtio_card.c
create mode 100644 sound/virtio/virtio_card.h
create mode 100644 sound/virtio/virtio_chmap.c
create mode 100644 sound/virtio/virtio_ctl_msg.c
create mode 100644 sound/virtio/virtio_ctl_msg.h
create mode 100644 sound/virtio/virtio_jack.c
create mode 100644 sound/virtio/virtio_pcm.c
create mode 100644 sound/virtio/virtio_pcm.h
create mode 100644 sound/virtio/virtio_pcm_msg.c
create mode 100644 sound/virtio/virtio_pcm_ops.c
--
2.30.0
3
27
Hi there,
A large number of audio codecs allow different formats for playback and
capture. This becomes very useful when there are different latencies
between playback and capture hardware data lines. For example digital
isolation chips typically have a 1 bit delay in propagation as the bit
clock rate gets faster for higher sample rates. By setting the capture
and playback formats to differ by one or two bit clock cycles, the delay
problem is solved.
There doesn't seem to be a simple way to detect stream direction in the
codec driver's set_fmt function.
The snd_soc_runtime_set_dai_fmt function :
https://github.com/torvalds/linux/blob/master/sound/soc/soc-core.c#L1480
calls the snd_soc_dai_set_fmt function :
https://github.com/torvalds/linux/blob/master/sound/soc/soc-dai.c#L101
which calls the set_fmt function :
https://github.com/torvalds/linux/blob/master/include/sound/soc-dai.h#L189
The snd_soc_dai_ops set_fmt function is defined as :
int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
Is there a simple way to find the stream direction from a snd_soc_dai ?
If the stream direction can be detected then the playback and capture
formats can be set independently for the codec.
It there a different way to set the playback and capture formats for the
codec independently at runtime, depending on the sample rate ?
Matt
5
8
[PATCH alsa-ucm-conf 0/8] codecs/rt5640: Cleanup + HW volume control support
by Hans de Goede 26 Feb '21
by Hans de Goede 26 Feb '21
26 Feb '21
Hi All,
Here is a patch series consisting of some codecs/rt5640 cleanups and
addition of HW volume control support to the rt5640 .conf snippets.
Note patch 7 and 8 depend on a new "aif:%d" part being added to the
components string, the kernel patches for this are pending upstream
in the "[PATCH 0/5] AsoC: rt5640/rt5651: Volume control fixes" patch
series.
Patches 7 and 8 should probably not be merged until the kernel patches
have landed, because theoretically the new component string part could
change as part of the review of the kernel patches.
Regards,
Hans
Hans de Goede (8):
codecs/rt5640: Cleanup: unify Stereo / Mono ADC handling
codecs/rt5640: Cleanup: Initially disable all inputs and outputs
codecs/rt5640: Cleanup: Move 'SPK MIX' setup to main EnableSequene
codecs/rt5640: Drop bogus 'DIG MIXL DAC L2 Switch' setting
codecs/rt5640: Unify capture volume for AIF1 and AIF2 recording paths
codecs/rt5640: Add hardware volume-control support
codecs/rt5640: Use the new "aif:%d" part of the components string
codecs/rt5640: Specify Playback/CaptureMasterElem for HW
volume-control
ucm2/bytcr-rt5640/HiFi.conf | 46 +++++++++++++++++
ucm2/codecs/rt5640/DigitalMics.conf | 18 ++++++-
ucm2/codecs/rt5640/EnableSeq-AIF-unknown.conf | 7 +++
ucm2/codecs/rt5640/EnableSeq-AIF1.conf | 7 +++
ucm2/codecs/rt5640/EnableSeq-AIF2.conf | 7 +++
ucm2/codecs/rt5640/EnableSeq.conf | 50 ++++++++++++++-----
ucm2/codecs/rt5640/HeadPhones.conf | 15 +++++-
ucm2/codecs/rt5640/HeadsetMic.conf | 24 ++++++---
ucm2/codecs/rt5640/IN1-InternalMic.conf | 27 ++++++----
ucm2/codecs/rt5640/IN3-InternalMic.conf | 27 ++++++----
ucm2/codecs/rt5640/MonoSpeaker.conf | 17 +++++--
ucm2/codecs/rt5640/Speaker.conf | 17 +++++--
12 files changed, 211 insertions(+), 51 deletions(-)
create mode 100644 ucm2/codecs/rt5640/EnableSeq-AIF-unknown.conf
create mode 100644 ucm2/codecs/rt5640/EnableSeq-AIF1.conf
create mode 100644 ucm2/codecs/rt5640/EnableSeq-AIF2.conf
--
2.30.1
1
8
Hey all,
The last few weeks I've been plagued by inconsistent audio on my PopOS
20.10 desktop. Sometimes on boot everything would be fine, but other
times I would have no working audio and only dummy devices in the
audio menus. I eventually found that if I specify the modprobe order
so that the USB driver (eg. for my webcam) loads after the onboard
motherboard driver, that audio will work consistently.
Here are the related links:
- Reddit thread where I posted the original problem and the solution:
https://www.reddit.com/r/pop_os/comments/lmvbj3/audio_not_working_after_upg…
- A related thread where it sounds like an arch user has the same
problem: https://bbs.archlinux.org/viewtopic.php?id=260373
- The alsa info I uploaded while under the effects of the problem:
http://alsa-project.org/db/?f=a23ccbb818fec6eaf08b032504eac5d5d8a30589
I'm not really sure where this problem originated but I figured you
guys might be able to point me in the right direction if it is not an
alsa problem.
I don't think I messed with the original alsa-base.conf but I suppose
my memory could be failing me here. I'm not sure where this file comes
from but I'm guessing it could be either a pop os, ubuntu, or alsa
default configuration?
Thanks,
Steven Skeard
1
0