Compare commits

...

45 commits

Author SHA1 Message Date
Jaroslav Kysela
187eeecd14 Release v1.2.14
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-14 10:26:23 +02:00
Andreas Persson
ddc93b66b4 envy24control: port to GTK 3
Closes: https://github.com/alsa-project/alsa-tools/pull/35
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-09 12:38:23 +02:00
Jaroslav Kysela
32495631b1 hdspmixer: correct string delimiter in labels_aio_ss_input
Closes: https://github.com/alsa-project/alsa-tools/issues/10
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-09 11:57:30 +02:00
Andreas Persson
837033a108 envy24control: fix GtkSpinButton runtime warnings
Change the parameters to gtk_adjustment_new to get rid of this runtime
warning from GTK:

GtkSpinButton: setting an adjustment with non-zero page size is
deprecated

The change is also important when envy24control is ported to GTK 3, as
the spin buttons will stop working if it's not done.

Closes: https://github.com/alsa-project/alsa-tools/pull/31
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-09 11:48:37 +02:00
Andreas Persson
65a201fed6 envy24control: fix memory access errors in profiles
Fix two memory errors in the profiles parser: an invalid read and a
"source and destination overlap in strncpy" warning.

When the profiles page is initialized it fetches the profile names from
the profiles file. When a profile wasn't defined in the file, the parser
made invalid reads outside the buffer.

Closes: https://github.com/alsa-project/alsa-tools/pull/34
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-09 11:44:37 +02:00
Andreas Persson
52e6481047 envy24control: fix file descriptor leaks in profiles
File descriptors were leaked when "Save active profile" was pressed. Add
the missing calls to close.

Closes: https://github.com/alsa-project/alsa-tools/pull/33
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-09 11:44:11 +02:00
Jaroslav Kysela
337768effa github: actions - create initial build.yaml
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-09 11:42:16 +02:00
Andreas Persson
037ae73ab3 envy24control: fix crash when using system profiles file
envy24control crashed if you tried to start it with -f
/etc/envy24control/profiles.conf.

Closes: https://github.com/alsa-project/alsa-tools/pull/32
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-08 15:23:11 +02:00
Andreas Persson
dcf1b94682 envy24control: fix control callback for spdif output
Update S/PDIF Output Settings GUI when settings change.

Closes: https://github.com/alsa-project/alsa-tools/pull/30
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-08 15:22:34 +02:00
Andreas Persson
4522439faf envy24control: simplify code by using gtk_widget_show_all
Remove all gtk_widget_show calls and replace it with just one
gtk_widget_show_all. This makes the code shorter and it will also help a
future port to GTK 4, where gtk_widget_show is gone.

Closes: https://github.com/alsa-project/alsa-tools/pull/29
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-08 15:22:27 +02:00
Andreas Persson
6d2d500456 envy24control: fix spdif output settings
The S/PDIF Output Settings in envy24control had some bugs: wrong bits
were set when user changed "Stream" under "Professional" or any of the
settings under "Consumer".

Closes: https://github.com/alsa-project/alsa-tools/pull/28
Signed-off-by: Andreas Persson <andreasp56@outlook.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-04-08 15:22:20 +02:00
Jaroslav Kysela
5eaadd15bd hdajackretask: fix reset_changes_boot() declaration
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 11:02:21 +01:00
Jaroslav Kysela
90c2aa2639 ld10k1: fix various gcc warnings
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
2420b2a6df echomixer: fix various gcc warnings
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
cd9ee08dcb vxloader: fix gcc warnings (string size)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
3bd780896e usx2yloader: fix gcc warnings (string size)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
a2a0167ed9 rmedigicontrol: fix gcc warnings (string size)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
48128777e0 pcxhrloader: fix gcc warnings (string truncation)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
9cb754084b mixartloader: fix gcc warnings (string truncation)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
6549725ec5 hdspconf: fix gcc warnings (const)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:25 +01:00
Jaroslav Kysela
787857d61a as10k1: fix gcc warnings
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-27 10:44:14 +01:00
Jaroslav Kysela
97092591e0 envy24control: fix cast warnings and string array overflows
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2025-01-26 13:08:20 +01:00
Takashi Iwai
54b5913cd5 hdajackretask: Fix build with gcc7
The old compiler doesn't allow a variable declaration inside switch
block.

Fixes: d349d20c12 ("hdajackretask: add support for pipewire stop/start")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-02-02 17:24:26 +01:00
Jaroslav Kysela
cb85b257b4 Release v1.2.11
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2024-01-29 13:57:31 +01:00
Jaroslav Kysela
aa2dc9b432 hdajackretask: limit the help window size to something safe (1600x1000) for the help screen
If more monitors are present in the system, the window is too big and information
cannot be visible correctly.

Fixes: https://github.com/alsa-project/alsa-tools/issues/20
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2024-01-25 13:29:03 +01:00
Jaroslav Kysela
d349d20c12 hdajackretask: add support for pipewire stop/start
Link: https://github.com/alsa-project/alsa-tools/issues/21
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2024-01-25 13:26:13 +01:00
Michael Tautschnig
f2985c9f33 as10k1: make (extern) declarations and definition of macro_depth
All `extern` declarations refer to it as `unsigned int`, but the actual
definition is a signed integer.

Reported by CBMC's goto-cc compiler, which performs type-aware linking.

Closes: https://github.com/alsa-project/alsa-tools/pull/19
Signed-off-by: Michael Tautschnig <tautschn@amazon.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2024-01-24 19:09:41 +01:00
Mazunki Hoksaas
4bfaf097e0 echomixer: fix clang-16 incompatible-function-pointer
Closes: https://github.com/alsa-project/alsa-tools/pull/17
Signed-off-by: Mazunki Hoksaas <rolferen@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2024-01-24 19:09:06 +01:00
wynnfeng
8c8d6941f2 hdspmixer: fix core dump
Initialize the name pointer to NULL.

Fixes: https://github.com/alsa-project/alsa-tools/pull/14
Signed-off-by: wynnfeng <wynnfeng@tencent.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2023-05-03 16:45:49 +02:00
Frank Dana
5b9c2cb399 hdajackretask: Update kernel doc URL in README
As of THIS writing, the documentation has been rearranged,
and the "Hint strings" section now resides at the updated URL

Fixes: https://github.com/alsa-project/alsa-tools/pull/2
Signed-off-by: Frank Dana <ferdnyc@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2023-05-03 16:44:50 +02:00
Jaroslav Kysela
78e579b3e3 Release v1.2.5
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-27 19:18:38 +02:00
Jasmin Fazlic
3e4fd7dffb 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:
da2a040ee7

We check whether the system has the kernel patch
applied by calling `HDSPMixerCard::supportsLoopback()`
and if not these buttons remain gray (off) and do
nothing when clicked.

Signed-off-by: Jasmin Fazlic <superfassl@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-02-27 09:24:53 +01:00
Jasmin Fazlic
c0e69055fa 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@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-02-27 09:24:08 +01:00
Jaroslav Kysela
82979c32e4 Release v1.2.2
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2020-02-19 10:35:44 +01:00
Takashi Iwai
534e7fac80 hdspmixer: Use __u32 and __u64 for RMS array types
Some variable types are referring to the field in ioctl struct, which
are actually __u32 or __u64 instead of uint32_t or uint64_t.
This inconsistency may result in the compile error.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-12-20 16:42:30 +01:00
Jaroslav Kysela
9ed2ebaaa7 Release v1.1.7
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2018-10-16 10:08:36 +02:00
Emmanuel Gil Peyrot
dc733d6b08 hwmixvolume: mention the new dependencies in the README
Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:09:18 +02:00
Emmanuel Gil Peyrot
88bd30b732 hwmixvolume: add my copyright
Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:09:08 +02:00
Emmanuel Gil Peyrot
fb043847de hwmixvolume: switch the shebang to python
This signifies that this code is now compatible with both Python 2 and
Python 3, as per PEP-0394[1].

[1] https://www.python.org/dev/peps/pep-0394/

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:08:55 +02:00
Emmanuel Gil Peyrot
213b28a5aa hwmixvolume: use a with context to open files
This feature has been added in Python 2.5 and automatically closes an
open file once the context exits.

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:08:27 +02:00
Emmanuel Gil Peyrot
a21dda3d86 hwmixvolume: switch to GTK+ 3.0 and GLib 2.0
This replaces VBox and HBox with Grid (using Gtk.Orientation), HScale
with Scale, creates labels with mnemonics, set hexpand and vexpand
properly, use the correct enum container classes, use the correct getter
for size request, and finally update to the correct GLib watch function.

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:07:56 +02:00
Emmanuel Gil Peyrot
0a9ad5c1e1 hwmixvolume: replace PyGTK with gobject-introspection
This doesn’t work yet, we require Gtk 3.0 rather than 2.0 and the API
changed quite a lot, so this is but a preparatory patch.

This is done so that we can get rid of GTK+ 2 which has been EOL for
many years already, and to add Python 3 support because Python 2 will
very soon be EOL as well.

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:07:04 +02:00
Emmanuel Gil Peyrot
50e9ac4e81 hwmixvolume: use four spaces instead of one tab for indent
This is the recommended coding style for all Python programs, as
specified in PEP-0008[1].

[1] https://www.python.org/dev/peps/pep-0008/

Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-09-20 09:06:11 +02:00
Ross Burton
235d9c5e83 ld10k1: define _GNU_SOURCE and use sighandler_t
__sighandler_t is a glibc internal type which doesn't exist in musl.  By using
AC_USE_SYSTEM_EXTENSIONS to get _GNU_SOURCE defined, both glibc and musl
then expose sighandler_t.

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-06-12 14:30:58 +02:00
Khem Raj
a861bdabf0 us428control: Fix clang -Wreserved-user-defined-literal warnings
| us428control.cc:66:18: error: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wreserved-user-defined-literal]
|         printf("usage: "PROGNAME" [-v verbosity_level 0..2] [-c card] [-D device] [-u usb-device] [-m mode]\n");
|                         ^

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-04-24 21:32:03 +02:00
68 changed files with 2155 additions and 1608 deletions

142
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,142 @@
name: Build alsa-tools
on: [push, pull_request]
jobs:
fedora_latest_build:
runs-on: ubuntu-latest
container:
image: fedora:latest
env:
QTDIR: /usr/lib64/qt-3.3
steps:
- name: Prepare environment
run: |
dnf -y upgrade
dnf -y install @development-tools gcc-c++ libtool bzip2 gtk2-devel gtk3-devel fltk-devel qt3-devel
- name: Checkout alsa-lib
uses: actions/checkout@v4
with:
repository: alsa-project/alsa-lib
ref: master
path: alsa-lib
- name: Configure alsa-lib
run: |
cd alsa-lib
head -5 configure.ac
libtoolize --force --copy --automake
aclocal
autoheader
automake --foreign --copy --add-missing
autoconf
export CFLAGS="-O2 -Wall -W -Wunused-const-variable=0 -pipe -g"
./configure
echo "Version: $(cat version)"
- name: Build alsa-lib
run: |
cd alsa-lib
make
- name: Install alsa-lib
run: |
cd alsa-lib
make install
- name: Checkout
uses: actions/checkout@v4
with:
path: alsa-tools
- name: Checkout all tags
run: |
cd alsa-tools
git fetch --prune --tags --force
git fetch --prune --unshallow --force
- name: Modify version
run: |
cd alsa-tools
mv Makefile Makefile.old
version=$(git describe | sed -e 's/v//')
if test -z "$version"; then version=$(git describe --tags | sed -e 's/v//'); fi
if test -z "$version"; then version1=$(grep "VERSION = .*" Makefile.old | cut -d ' ' -f 3); version2=$(git rev-parse --short HEAD); version="${version1}-g${version2}"; fi
echo "Version: ${version}"
sed -r "s/VERSION = .*/VERSION = ${version}/" < Makefile.old > Makefile
grep "VERSION =" Makefile
- name: Compile and install as10k1 (dependency)
run: |
cd alsa-tools/as10k1
./gitcompile --prefix=/usr
make install
- name: Compile and install ld10k1 (dependency)
run: |
cd alsa-tools/ld10k1
./gitcompile --prefix=/usr
make install
- name: Configure and build
run: |
cd alsa-tools
./gitcompile
- name: Create package
run: |
cd alsa-tools
make alsa-dist
mkdir ../artifacts
mv alsa-tools*.tar.bz2 ../artifacts
- name: Archive package
uses: actions/upload-artifact@v4
with:
name: alsa-tools-test-package
path: artifacts/
ubuntu_last_build:
runs-on: ubuntu-latest
container:
image: ubuntu:latest
steps:
- name: Prepare
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get -y install apt-utils
apt-get -y full-upgrade
apt-get install -y git build-essential pkg-config m4 autoconf automake libtool ibgtk2.0-dev libgtk-3-dev libfltk1.3-dev
- name: Checkout alsa-lib
uses: actions/checkout@v4
with:
repository: alsa-project/alsa-lib
ref: master
- name: Configure alsa-lib
run: |
libtoolize --force --copy --automake
aclocal
autoheader
automake --foreign --copy --add-missing
autoconf
export CFLAGS="-O2 -Wall -W -Wunused-const-variable=0 -pipe -g"
./configure
- name: Build alsa-lib
run: |
make
- name: Install alsa-lib
run: |
make install
- name: Checkout
uses: actions/checkout@v4
- name: Remove qlo10k1
run: |
mv Makefile Makefile.old
sed -e 's/qlo10k1//' < Makefile.old > Makefile
- name: Compile and install as10k1 (dependency)
run: |
cd as10k1
./gitcompile --prefix=/usr
make install
- name: Compile and install ld10k1 (dependency)
run: |
cd ld10k1
./gitcompile --prefix=/usr
make install
- name: Configure and build
run: |
./gitcompile

View file

@ -1,4 +1,4 @@
VERSION = 1.1.6
VERSION = 1.2.14
TOP = .
SUBDIRS = as10k1 envy24control hdsploader hdspconf hdspmixer \
mixartloader pcxhrloader rmedigicontrol sb16_csp seq sscape_ctl \

View file

@ -244,6 +244,7 @@ void asm_open(char *name)
struct stat st;
char *next;
int backup_line_num,backup_file_num;
size_t rsize;
@ -284,8 +285,10 @@ void asm_open(char *name)
buff[i].mem_end = buff[i].mem_start+st.st_size;
read(fd, buff[i].mem_start, st.st_size);
rsize = read(fd, buff[i].mem_start, st.st_size);
close(fd);
if (rsize != st.st_size)
as_exit("short read from input file\n");
#ifdef DEBUG
printf("File %s opened:\n",name);
@ -383,13 +386,14 @@ void output_tram_line(struct list_head *line_head, int type)
val = __cpu_to_le32(tram_sym->data.value);
fwrite(&val,sizeof(u32),1,fp);
if(listing){
if(type==TYPE_TRAM_ADDR_READ)
if(type==TYPE_TRAM_ADDR_READ) {
fprintf(listfile,"\tRead");
else
} else {
fprintf(listfile,"\tWrite");
}
fprintf(listfile,": 0x3%02x/0x2%02x (%s), offset 0x%07x\n",tram_sym->data.address,tram_sym->data.address,
(prev_sym((&tram_sym->list)))->data.name,tram_sym->data.value);
fprintf(listfile,": 0x3%02x/0x2%02x (%s), offset 0x%07x\n",tram_sym->data.address,tram_sym->data.address,
(prev_sym((&tram_sym->list)))->data.name,tram_sym->data.value);
}
}

View file

@ -55,6 +55,6 @@ int tram_table_count=0;
int gpr_constant_count=0;
char patch_name[PATCH_NAME_SIZE]="NO_NAME";
int macro_depth=0;
unsigned int macro_depth=0;

View file

@ -22,6 +22,7 @@
#include"types.h"
#include"proto.h"
#include"parse.h"
extern int dbg_opt;
extern FILE *listfile;
@ -45,7 +46,6 @@ void op(int op, int z,int w,int x,int y)
int w0, w1;
extern int dsp_code[DSP_CODE_SIZE];
extern int ip;
extern char op_codes[35][9];
extern char listtemp[60];
if (ip >= 0x200)
as_exit("to many instructions");
@ -306,7 +306,6 @@ void add_symbol(char *name, u16 type, u16 address, u32 value)
extern int gpr_input_count,gpr_output_count,gpr_static_count,gpr_dynamic_count,gpr_control_count,gpr_constant_count;
struct sym *sym;
struct tram *tmp_ptr;
extern struct list_head sym_head;
extern struct delay tram_delay[MAX_TANK_ADDR];
extern struct lookup tram_lookup[MAX_TANK_ADDR];
@ -356,10 +355,8 @@ void add_symbol(char *name, u16 type, u16 address, u32 value)
else
tram_delay[tmp].write++;
}else{
tmp_ptr=(struct tram *)sym;
list_add_tail(&(((struct tram *)sym)->tram) , &(tram_lookup[tmp].tram) );
tmp_ptr=(struct tram *)sym;
if(type== TYPE_TRAM_ADDR_READ)
if(type== TYPE_TRAM_ADDR_READ)
tram_lookup[tmp].read++;
else
tram_lookup[tmp].write++;

View file

@ -72,14 +72,11 @@ void new_macro(char *symbol, char *line, char *operand)
void macro_expand(int macnum,char *operand )
{
char *line,*next;
int done=0,i,old;
int done=0,old;
extern unsigned int macro_depth;
extern int macro_line_num;
char string[MAX_LINE_LENGTH];
//initialize macro use:
i=0;
if(macro_depth+1> MAX_MAC_DEPTH)
as_exit("Error exceeded maximum number of recursive macro calls");

View file

@ -18,6 +18,7 @@
#include<string.h>
#include<stdio.h>
#include"types.h"
#define DECLARE_OP_CODES
#include"parse.h"
#include"proto.h"
@ -87,7 +88,7 @@ int parse( char line_string[MAX_LINE_LENGTH], char *line)
if((tmp=ismacro(op_name_ptr)) != -1 ){
if(defmacro==0)
macro_expand(tmp,strtok(NULL,""));
return(0);
return(0);
}
if( (op_num=op_decode(op_name_ptr))==-1) {

View file

@ -63,7 +63,9 @@ enum foo {
};
#ifndef DECLARE_OP_CODES
extern char op_codes[NUM_OPS+1][9];
#else
char op_codes[NUM_OPS+1][9]=
{
"MACS",
@ -110,6 +112,7 @@ char op_codes[NUM_OPS+1][9]=
"con",
"NotAnOp"
};
#endif
//extern int file_num,source_line_num

View file

@ -629,9 +629,7 @@ gint DrawMixer(gpointer unused) {
int OutPeak[ECHO_MAXAUDIOOUTPUTS];
int VirLevel[ECHO_MAXAUDIOOUTPUTS];
int VirPeak[ECHO_MAXAUDIOOUTPUTS];
static int InClip[ECHO_MAXAUDIOINPUTS];
static int OutClip[ECHO_MAXAUDIOOUTPUTS];
char str[8];
char str[16];
int i, o, dB;
GdkColor Grid={0x787878, 0, 0, 0};
GdkColor Labels={0x9694C4, 0, 0, 0};
@ -647,13 +645,8 @@ gint DrawMixer(gpointer unused) {
update_rect.height = Mixheight;
GetVUmeters(InLevel, InPeak, OutLevel, OutPeak, VirLevel, VirPeak);
if (!gc) {
if (!gc)
gc=gdk_gc_new(gtk_widget_get_parent_window(Mixdarea));
for (i=0; i<nIn; i++)
InClip[i]=0;
for (i=0; i<nLOut; i++)
OutClip[i]=0;
}
gdk_draw_rectangle(Mixpixmap, Mixdarea->style->black_gc, TRUE, 0, 0, Mixwidth, Mixheight);
@ -1693,7 +1686,7 @@ void ToggleWindow(GtkWidget *widget, gpointer window) {
// Scan all controls and sets up the structures needed to access them.
int OpenControls(const char *card, const char *cardname) {
int err, i, o;
int numid, count, items, item;
int numid, items, item;
snd_hctl_t *handle;
snd_hctl_elem_t *elem;
snd_ctl_elem_id_t *id;
@ -1726,7 +1719,6 @@ int OpenControls(const char *card, const char *cardname) {
continue;
snd_hctl_elem_get_id(elem, id);
numid=snd_ctl_elem_id_get_numid(id);
count=snd_ctl_elem_info_get_count(info);
if (!strcmp("Monitor Mixer Volume", snd_ctl_elem_id_get_name(id))) {
if (!mixerId) {
mixerId=numid;
@ -1879,7 +1871,7 @@ int main(int argc, char *argv[]) {
GtkWidget *label, *menu, *menuitem;
GSList *bgroup;
int err, i, o, n, cardnum, value;
char hwname[8], cardname[32], load, save;
char hwname[16], cardname[32], load, save;
snd_ctl_card_info_t *hw_info;
load=save=1;
@ -1900,8 +1892,8 @@ int main(int argc, char *argv[]) {
}
if ((err=snd_ctl_card_info(ctlhandle, hw_info))>=0) {
if (!strncmp(snd_ctl_card_info_get_driver(hw_info), "Echo_", 5)) {
strncpy(card, hwname, 7);
hwname[7]=0;
strncpy(card, hwname, sizeof(hwname)-1);
card[sizeof(hwname)-1]=0;
strncpy(cardname, snd_ctl_card_info_get_name(hw_info), 31);
cardname[31]=0;
strncpy(cardId, snd_ctl_card_info_get_name(hw_info), 15);
@ -2105,7 +2097,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
for (i=0; i<ndmodes; i++) {
menuitem=gtk_menu_item_new_with_label(dmodeName[i]);
gtk_widget_show(menuitem);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate", Digital_mode_activate, (gpointer)(long)i);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate", G_CALLBACK(Digital_mode_activate), (gpointer)(long)i);
gtk_menu_append(GTK_MENU(menu), menuitem);
}
gtk_option_menu_set_menu(GTK_OPTION_MENU(dmodeOpt), menu);
@ -2131,7 +2123,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
clocksrc_menuitem[i]=gtk_menu_item_new_with_label(clocksrcName[i]);
gtk_widget_show(clocksrc_menuitem[i]);
gtk_widget_set_sensitive(clocksrc_menuitem[i], FALSE);
gtk_signal_connect(GTK_OBJECT(clocksrc_menuitem[i]), "activate", Clock_source_activate, (gpointer)(long)i);
gtk_signal_connect(GTK_OBJECT(clocksrc_menuitem[i]), "activate", G_CALLBACK(Clock_source_activate), (gpointer)(long)i);
gtk_menu_append(GTK_MENU(menu), clocksrc_menuitem[i]);
}
gtk_option_menu_set_menu(GTK_OPTION_MENU(clocksrcOpt), menu);
@ -2157,7 +2149,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
for (i=0; i<nspdifmodes; i++) {
menuitem=gtk_menu_item_new_with_label(spdifmodeName[i]);
gtk_widget_show(menuitem);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate", SPDIF_mode_activate, (gpointer)(long)i);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate", G_CALLBACK(SPDIF_mode_activate), (gpointer)(long)i);
gtk_menu_append(GTK_MENU(menu), menuitem);
}
gtk_option_menu_set_menu(GTK_OPTION_MENU(spdifmodeOpt), menu);
@ -2182,7 +2174,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0);
ReadControl(&i, 1, PhantomPower.id, SND_CTL_ELEM_IFACE_MIXER);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), i);
gtk_signal_connect(GTK_OBJECT(button), "toggled", Switch_toggled, (gpointer)&PhantomPower);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(Switch_toggled), (gpointer)&PhantomPower);
PhantomPower.Button=button;
}
@ -2193,7 +2185,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0);
ReadControl(&i, 1, Automute.id, SND_CTL_ELEM_IFACE_CARD);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), i);
gtk_signal_connect(GTK_OBJECT(button), "toggled", Switch_toggled, (gpointer)&Automute);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(Switch_toggled), (gpointer)&Automute);
Automute.Button=button;
}
@ -2202,7 +2194,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
autoclockChkbutton=gtk_check_button_new_with_label("Autoclock");
gtk_widget_show(autoclockChkbutton);
gtk_box_pack_start(GTK_BOX(hbox), autoclockChkbutton, TRUE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(autoclockChkbutton), "toggled", AutoClock_toggled, NULL);
gtk_signal_connect(GTK_OBJECT(autoclockChkbutton), "toggled", G_CALLBACK(AutoClock_toggled), NULL);
AutoClock=-1;
}
}
@ -2672,7 +2664,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), 1);
gtk_widget_show(button);
gtk_signal_connect(GTK_OBJECT(button), "toggled", Gang_button_toggled, 0);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(Gang_button_toggled), 0);
// Controls frame
frame=gtk_frame_new("Controls");
@ -2687,7 +2679,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("VU");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", VUmeters_button_click, 0);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(VUmeters_button_click), 0);
VUw_geom.toggler=button;
if (VUw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@ -2697,7 +2689,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("Line");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)LVwindow);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(ToggleWindow), (gpointer)LVwindow);
LVw_geom.toggler=button;
if (LVw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@ -2707,7 +2699,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("Misc");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)Miscwindow);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(ToggleWindow), (gpointer)Miscwindow);
Miscw_geom.toggler=button;
if (Miscw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@ -2718,7 +2710,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("GrMix");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", GMixer_button_click, 0);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(GMixer_button_click), 0);
GMw_geom.toggler=button;
if (GMw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@ -2727,7 +2719,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("Mixer");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)mixerControl.window);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(ToggleWindow), (gpointer)mixerControl.window);
Mixerw_geom.toggler=button;
if (Mixerw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@ -2738,7 +2730,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("Vmixer");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)vmixerControl.window);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(ToggleWindow), (gpointer)vmixerControl.window);
Vmixerw_geom.toggler=button;
if (Vmixerw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
@ -2749,7 +2741,7 @@ printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/
button=gtk_toggle_button_new_with_label("PCM");
gtk_widget_show(button);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1);
gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)pcmoutControl.window);
gtk_signal_connect(GTK_OBJECT(button), "toggled", G_CALLBACK(ToggleWindow), (gpointer)pcmoutControl.window);
PVw_geom.toggler=button;
if (PVw_geom.st==1)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);

View file

@ -46,8 +46,8 @@ void config_close()
void config_set_stereo(GtkWidget *but, gpointer data)
{
gint i=(gint)data;
config_stereo[i]=GTK_TOGGLE_BUTTON(but)->active;
gint i=GPOINTER_TO_INT(data);
config_stereo[i]=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(but));
}
void config_restore_stereo()

View file

@ -5,6 +5,6 @@ AC_HEADER_STDC
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE([enable])
PKG_CHECK_MODULES(ENVY24CONTROL, gtk+-2.0 alsa >= 0.9.0)
PKG_CHECK_MODULES(ENVY24CONTROL, gtk+-3.0 alsa >= 0.9.0)
AC_OUTPUT(Makefile desktop/Makefile)

View file

@ -19,7 +19,7 @@
#include "envy24control.h"
void control_input_callback(gpointer data, gint source, GdkInputCondition condition)
gboolean control_input_callback(GIOChannel *source, GIOCondition condition, gpointer data)
{
snd_ctl_t *ctl = (snd_ctl_t *)data;
snd_ctl_event_t *ev;
@ -29,12 +29,12 @@ void control_input_callback(gpointer data, gint source, GdkInputCondition condit
snd_ctl_event_alloca(&ev);
if (snd_ctl_read(ctl, ev) < 0)
return;
return TRUE;
name = snd_ctl_event_elem_get_name(ev);
index = snd_ctl_event_elem_get_index(ev);
mask = snd_ctl_event_elem_get_mask(ev);
if (! (mask & (SND_CTL_EVENT_MASK_VALUE | SND_CTL_EVENT_MASK_INFO)))
return;
return TRUE;
switch (snd_ctl_event_elem_get_interface(ev)) {
case SND_CTL_ELEM_IFACE_MIXER:
@ -81,8 +81,13 @@ void control_input_callback(gpointer data, gint source, GdkInputCondition condit
else if (!strcmp(name, "Input Sensitivity Switch"))
adc_sense_update(index);
break;
case SND_CTL_ELEM_IFACE_PCM:
if (!strcmp(name, "IEC958 Playback Default"))
spdif_output_update();
break;
default:
break;
}
return TRUE;
}

File diff suppressed because it is too large Load diff

View file

@ -85,7 +85,7 @@ extern ice1712_eeprom_t card_eeprom;
extern GtkWidget *mixer_mix_drawing;
extern GtkWidget *mixer_clear_peaks_button;
extern GtkWidget *mixer_drawing[20];
extern GtkObject *mixer_adj[20][2];
extern GtkAdjustment *mixer_adj[20][2];
extern GtkWidget *mixer_vscale[20][2];
extern GtkWidget *mixer_solo_toggle[20][2];
extern GtkWidget *mixer_mute_toggle[20][2];
@ -108,7 +108,7 @@ extern GtkWidget *hw_master_clock_actual_rate_label;
extern GtkWidget *hw_rate_locking_check;
extern GtkWidget *hw_rate_reset_check;
extern GtkObject *hw_volume_change_adj;
extern GtkAdjustment *hw_volume_change_adj;
extern GtkWidget *hw_volume_change_spin;
extern GtkWidget *hw_spdif_profi_nonaudio_radio;
@ -151,9 +151,9 @@ extern GtkWidget *input_interface_internal;
extern GtkWidget *input_interface_front_input;
extern GtkWidget *input_interface_rear_input;
extern GtkWidget *input_interface_wavetable;
extern GtkObject *av_dac_volume_adj[];
extern GtkObject *av_adc_volume_adj[];
extern GtkObject *av_ipga_volume_adj[];
extern GtkAdjustment *av_dac_volume_adj[];
extern GtkAdjustment *av_adc_volume_adj[];
extern GtkAdjustment *av_ipga_volume_adj[];
extern GtkLabel *av_dac_volume_label[];
extern GtkLabel *av_adc_volume_label[];
extern GtkLabel *av_ipga_volume_label[];
@ -163,8 +163,7 @@ extern GtkWidget *av_adc_sense_radio[][4];
/* flags */
extern int card_is_dmx6fire;
gint level_meters_configure_event(GtkWidget *widget, GdkEventConfigure *event);
gint level_meters_expose_event(GtkWidget *widget, GdkEventExpose *event);
gboolean level_meters_draw_callback(GtkWidget *widget, cairo_t *cr, gpointer data);
gint level_meters_timeout_callback(gpointer data);
void level_meters_reset_peaks(GtkButton *button, gpointer data);
void level_meters_init(void);
@ -238,6 +237,5 @@ void ipga_volume_adjust(GtkAdjustment *adj, gpointer data);
void dac_sense_toggled(GtkWidget *togglebutton, gpointer data);
void adc_sense_toggled(GtkWidget *togglebutton, gpointer data);
void control_input_callback(gpointer data, gint source, GdkInputCondition condition);
void mixer_input_callback(gpointer data, gint source, GdkInputCondition condition);
gboolean control_input_callback(GIOChannel *gio, GIOCondition condition, gpointer data);

View file

@ -39,7 +39,14 @@ static inline int is_update_needed(void);
static int is_active(GtkWidget *widget)
{
return GTK_TOGGLE_BUTTON(widget)->active ? 1 : 0;
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? 1 : 0;
}
static void label_set(GtkWidget* widget, const char* str)
{
const char* old = gtk_label_get_text(GTK_LABEL(widget));
if (strcmp(old, str))
gtk_label_set_text(GTK_LABEL(widget), str);
}
void master_clock_update(void)
@ -170,8 +177,8 @@ gint master_clock_status_timeout_callback(gpointer data)
snd_ctl_elem_value_set_name(sw, "Word Clock Status");
if ((err = snd_ctl_elem_read(ctl, sw)) < 0)
g_print("Unable to determine word clock status: %s\n", snd_strerror(err));
gtk_label_set_text(GTK_LABEL(hw_master_clock_status_label),
snd_ctl_elem_value_get_boolean(sw, 0) ? "No signal" : "Locked");
label_set(hw_master_clock_status_label,
snd_ctl_elem_value_get_boolean(sw, 0) ? "No signal" : "Locked");
return TRUE;
}
@ -246,7 +253,7 @@ gint internal_clock_status_timeout_callback(gpointer data)
}
}
}
gtk_label_set_text(GTK_LABEL(hw_master_clock_actual_rate_label), label);
label_set(hw_master_clock_actual_rate_label, label);
return TRUE;
}
@ -354,7 +361,7 @@ void volume_change_rate_adj(GtkAdjustment *adj, gpointer data)
{
int err;
snd_ctl_elem_value_set_integer(volume_rate, 0, adj->value);
snd_ctl_elem_value_set_integer(volume_rate, 0, gtk_adjustment_get_value(adj));
if ((err = snd_ctl_elem_write(ctl, volume_rate)) < 0)
g_print("Unable to write volume change rate: %s\n", snd_strerror(err));
}
@ -455,9 +462,9 @@ void profi_stream_toggled(GtkWidget *togglebutton, gpointer data)
return;
iec958.status[1] &= ~IEC958_AES1_PRO_MODE;
if (!strcmp(str, "NOTID")) {
iec958.status[0] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
iec958.status[1] |= IEC958_AES1_PRO_MODE_NOTID;
} else if (!strcmp(str, "Stereo")) {
iec958.status[0] |= IEC958_AES1_PRO_MODE_NOTID;
iec958.status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
}
snd_ctl_elem_value_set_iec958(spdif_output, &iec958);
spdif_output_write();
@ -500,7 +507,7 @@ void consumer_copyright_toggled(GtkWidget *togglebutton, gpointer data)
if (!strcmp(str, "Copyright")) {
iec958.status[0] &= ~IEC958_AES0_CON_NOT_COPYRIGHT;
} else if (!strcmp(str, "Permitted")) {
iec958.status[1] |= IEC958_AES0_CON_NOT_COPYRIGHT;
iec958.status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
}
snd_ctl_elem_value_set_iec958(spdif_output, &iec958);
spdif_output_write();
@ -517,9 +524,9 @@ void consumer_copy_toggled(GtkWidget *togglebutton, gpointer data)
if (iec958.status[0] & IEC958_AES0_PROFESSIONAL)
return;
if (!strcmp(str, "1st")) {
iec958.status[0] |= IEC958_AES1_CON_ORIGINAL;
} else if (!strcmp(str, "Original")) {
iec958.status[1] &= ~IEC958_AES1_CON_ORIGINAL;
} else if (!strcmp(str, "Original")) {
iec958.status[1] |= IEC958_AES1_CON_ORIGINAL;
}
snd_ctl_elem_value_set_iec958(spdif_output, &iec958);
spdif_output_write();
@ -539,7 +546,7 @@ void consumer_emphasis_toggled(GtkWidget *togglebutton, gpointer data)
if (!strcmp(str, "No")) {
iec958.status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
} else if (!strcmp(str, "5015")) {
iec958.status[1] |= ~IEC958_AES0_CON_EMPHASIS_5015;
iec958.status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
}
snd_ctl_elem_value_set_iec958(spdif_output, &iec958);
spdif_output_write();
@ -555,15 +562,15 @@ void consumer_category_toggled(GtkWidget *togglebutton, gpointer data)
return;
if (iec958.status[0] & IEC958_AES0_PROFESSIONAL)
return;
iec958.status[0] &= ~IEC958_AES1_CON_CATEGORY;
iec958.status[1] &= ~IEC958_AES1_CON_CATEGORY;
if (!strcmp(str, "DAT")) {
iec958.status[0] |= IEC958_AES1_CON_DAT;
iec958.status[1] |= IEC958_AES1_CON_DAT;
} else if (!strcmp(str, "PCM")) {
iec958.status[0] |= IEC958_AES1_CON_PCM_CODER;
iec958.status[1] |= IEC958_AES1_CON_PCM_CODER;
} else if (!strcmp(str, "CD")) {
iec958.status[0] |= IEC958_AES1_CON_IEC908_CD;
iec958.status[1] |= IEC958_AES1_CON_IEC908_CD;
} else if (!strcmp(str, "General")) {
iec958.status[0] |= IEC958_AES1_CON_GENERAL;
iec958.status[1] |= IEC958_AES1_CON_GENERAL;
}
snd_ctl_elem_value_set_iec958(spdif_output, &iec958);
spdif_output_write();
@ -598,7 +605,7 @@ void spdif_output_toggled(GtkWidget *togglebutton, gpointer data)
page = 1;
}
spdif_output_write();
gtk_notebook_set_page(GTK_NOTEBOOK(hw_spdif_output_notebook), page);
gtk_notebook_set_current_page(GTK_NOTEBOOK(hw_spdif_output_notebook), page);
spdif_output_update();
}
}

View file

@ -19,13 +19,13 @@
#include "envy24control.h"
static GdkGC *penGreenShadow[21] = { NULL, };
static GdkGC *penGreenLight[21] = { NULL, };
static GdkGC *penOrangeShadow[21] = { NULL, };
static GdkGC *penOrangeLight[21] = { NULL, };
static GdkGC *penRedShadow[21] = { NULL, };
static GdkGC *penRedLight[21] = { NULL, };
static GdkPixmap *pixmap[21] = { NULL, };
static GdkRGBA *penGreenShadow = NULL;
static GdkRGBA *penGreenLight = NULL;
static GdkRGBA *penOrangeShadow = NULL;
static GdkRGBA *penOrangeLight = NULL;
static GdkRGBA *penRedShadow = NULL;
static GdkRGBA *penRedLight = NULL;
static int level[22] = { 0 };
static snd_ctl_elem_value_t *peaks;
extern int input_channels, output_channels, pcm_output_channels, spdif_channels, view_spdif_playback;
@ -50,22 +50,19 @@ static void get_levels(int idx, int *l1, int *l2)
}
}
static GdkGC *get_pen(int idx, int nRed, int nGreen, int nBlue)
static GdkRGBA *get_pen(int nRed, int nGreen, int nBlue)
{
GdkColor *c;
GdkGC *gc;
GdkRGBA *c;
c = (GdkColor *)g_malloc(sizeof(GdkColor));
c->red = nRed;
c->green = nGreen;
c->blue = nBlue;
gdk_color_alloc(gdk_colormap_get_system(), c);
gc = gdk_gc_new(pixmap[idx]);
gdk_gc_set_foreground(gc, c);
return gc;
c = (GdkRGBA *)g_malloc(sizeof(GdkRGBA));
c->red = nRed / 65535.0;
c->green = nGreen / 65535.0;
c->blue = nBlue / 65535.0;
c->alpha = 1.0;
return c;
}
static int get_index(gchar *name)
static int get_index(const gchar *name)
{
int result;
@ -79,7 +76,7 @@ static int get_index(gchar *name)
return result;
}
static void redraw_meters(int idx, int width, int height, int level1, int level2)
static void redraw_meters(int idx, int width, int height, int level1, int level2, cairo_t *cr)
{
int stereo = idx == 0;
int segment_width = stereo ? (width / 2) - 8 : width - 12;
@ -90,167 +87,156 @@ static void redraw_meters(int idx, int width, int height, int level1, int level2
int seg;
int segs_on1 = ((segments * level1) + 128) / 255;
int segs_on2 = ((segments * level2) + 128) / 255;
int end_seg;
GdkRectangle clip;
// g_print("segs_on1 = %i (%i), segs_on2 = %i (%i)\n", segs_on1, level1, segs_on2, level2);
for (seg = 0; seg < green_segments; seg++) {
gdk_draw_rectangle(pixmap[idx],
segs_on1 > 0 ? penGreenLight[idx] : penGreenShadow[idx],
TRUE,
6, 3 + ((segments - seg - 1) * 4),
segment_width,
3);
if (stereo)
gdk_draw_rectangle(pixmap[idx],
segs_on2 > 0 ? penGreenLight[idx] : penGreenShadow[idx],
TRUE,
2 + (width / 2),
3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_rectangle(cr, 0, 0, width, height);
cairo_fill(cr);
gdk_cairo_get_clip_rectangle(cr, &clip);
seg = segments - (clip.y + clip.height) / 4;
if (seg < 0)
seg = 0;
segs_on1 -= seg;
segs_on2 -= seg;
end_seg = segments - (clip.y - 2) / 4;
for (; seg < green_segments && seg < end_seg; seg++) {
gdk_cairo_set_source_rgba(cr,
segs_on1 > 0 ? penGreenLight : penGreenShadow);
cairo_rectangle(cr,
6, 3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_fill(cr);
if (stereo) {
gdk_cairo_set_source_rgba(cr,
segs_on2 > 0 ? penGreenLight : penGreenShadow);
cairo_rectangle(cr,
2 + (width / 2),
3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_fill(cr);
}
segs_on1--;
segs_on2--;
}
for (seg = green_segments; seg < green_segments + orange_segments; seg++) {
gdk_draw_rectangle(pixmap[idx],
segs_on1 > 0 ? penOrangeLight[idx] : penOrangeShadow[idx],
TRUE,
6, 3 + ((segments - seg - 1) * 4),
segment_width,
3);
if (stereo)
gdk_draw_rectangle(pixmap[idx],
segs_on2 > 0 ? penOrangeLight[idx] : penOrangeShadow[idx],
TRUE,
2 + (width / 2),
3 + ((segments - seg - 1) * 4),
segment_width,
3);
for (; seg < green_segments + orange_segments && seg < end_seg; seg++) {
gdk_cairo_set_source_rgba(cr,
segs_on1 > 0 ? penOrangeLight : penOrangeShadow);
cairo_rectangle(cr,
6, 3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_fill(cr);
if (stereo) {
gdk_cairo_set_source_rgba(cr,
segs_on2 > 0 ? penOrangeLight : penOrangeShadow);
cairo_rectangle(cr,
2 + (width / 2),
3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_fill(cr);
}
segs_on1--;
segs_on2--;
}
for (seg = green_segments + orange_segments; seg < segments; seg++) {
gdk_draw_rectangle(pixmap[idx],
segs_on1 > 0 ? penRedLight[idx] : penRedShadow[idx],
TRUE,
6, 3 + ((segments - seg - 1) * 4),
segment_width,
3);
if (stereo)
gdk_draw_rectangle(pixmap[idx],
segs_on2 > 0 ? penRedLight[idx] : penRedShadow[idx],
TRUE,
2 + (width / 2),
3 + ((segments - seg - 1) * 4),
segment_width,
3);
for (; seg < segments && seg < end_seg; seg++) {
gdk_cairo_set_source_rgba(cr,
segs_on1 > 0 ? penRedLight : penRedShadow);
cairo_rectangle(cr,
6, 3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_fill(cr);
if (stereo) {
gdk_cairo_set_source_rgba(cr,
segs_on2 > 0 ? penRedLight : penRedShadow);
cairo_rectangle(cr,
2 + (width / 2),
3 + ((segments - seg - 1) * 4),
segment_width,
3);
cairo_fill(cr);
}
segs_on1--;
segs_on2--;
}
}
gint level_meters_configure_event(GtkWidget *widget, GdkEventConfigure *event)
{
int idx = get_index(gtk_widget_get_name(widget));
if (pixmap[idx] != NULL)
gdk_pixmap_unref(pixmap[idx]);
pixmap[idx] = gdk_pixmap_new(widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
penGreenShadow[idx] = get_pen(idx, 0, 0x77ff, 0);
penGreenLight[idx] = get_pen(idx, 0, 0xffff, 0);
penOrangeShadow[idx] = get_pen(idx, 0xddff, 0x55ff, 0);
penOrangeLight[idx] = get_pen(idx, 0xffff, 0x99ff, 0);
penRedShadow[idx] = get_pen(idx, 0xaaff, 0, 0);
penRedLight[idx] = get_pen(idx, 0xffff, 0, 0);
gdk_draw_rectangle(pixmap[idx],
widget->style->black_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
// g_print("configure: %i:%i\n", widget->allocation.width, widget->allocation.height);
redraw_meters(idx, widget->allocation.width, widget->allocation.height, 0, 0);
return TRUE;
}
gint level_meters_expose_event(GtkWidget *widget, GdkEventExpose *event)
gboolean level_meters_draw_callback(GtkWidget *widget, cairo_t *cr, gpointer data)
{
int idx = get_index(gtk_widget_get_name(widget));
int l1, l2;
get_levels(idx, &l1, &l2);
redraw_meters(idx, widget->allocation.width, widget->allocation.height, l1, l2);
gdk_draw_pixmap(widget->window,
widget->style->black_gc,
pixmap[idx],
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
redraw_meters(idx, gtk_widget_get_allocated_width(widget), gtk_widget_get_allocated_height(widget), l1, l2, cr);
return FALSE;
}
static void update_meter(int idx)
{
int stereo = idx == 0;
GtkWidget *widget = stereo ? mixer_mix_drawing : mixer_drawing[idx - 1];
int width = gtk_widget_get_allocated_width(widget);
int height = gtk_widget_get_allocated_height(widget);
int segments = (height - 6) / 4;
int level_idx = stereo ? 20 : idx - 1;
int l1, l2, segs_on, old_segs_on, h;
get_levels(idx, &l1, &l2);
segs_on = ((segments * l1) + 128) / 255;
old_segs_on = ((segments * level[level_idx]) + 128) / 255;
h = abs(old_segs_on - segs_on);
level[level_idx] = l1;
if (h > 0) {
int y = segments - MAX(old_segs_on, segs_on);
gtk_widget_queue_draw_area(widget,
6, 4 * y + 3,
stereo ? (width / 2) - 8 : width - 12,
4 * h - 1);
}
if (stereo) {
level_idx++;
segs_on = ((segments * l2) + 128) / 255;
old_segs_on = ((segments * level[level_idx]) + 128) / 255;
h = abs(old_segs_on - segs_on);
level[level_idx] = l2;
if (h > 0) {
int y = segments - MAX(old_segs_on, segs_on);
gtk_widget_queue_draw_area(widget,
2 + (width / 2), 4 * y + 3,
(width / 2) - 8,
4 * h - 1);
}
}
}
gint level_meters_timeout_callback(gpointer data)
{
GtkWidget *widget;
int idx, l1, l2;
int idx;
update_peak_switch();
for (idx = 0; idx <= pcm_output_channels; idx++) {
get_levels(idx, &l1, &l2);
widget = idx == 0 ? mixer_mix_drawing : mixer_drawing[idx-1];
if (GTK_WIDGET_VISIBLE(widget) && (pixmap[idx] != NULL)) {
redraw_meters(idx, widget->allocation.width, widget->allocation.height, l1, l2);
gdk_draw_pixmap(widget->window,
widget->style->black_gc,
pixmap[idx],
0, 0,
0, 0,
widget->allocation.width, widget->allocation.height);
}
update_meter(idx);
}
if (view_spdif_playback) {
for (idx = MAX_PCM_OUTPUT_CHANNELS + 1; idx <= MAX_OUTPUT_CHANNELS + spdif_channels; idx++) {
get_levels(idx, &l1, &l2);
widget = idx == 0 ? mixer_mix_drawing : mixer_drawing[idx-1];
if (GTK_WIDGET_VISIBLE(widget) && (pixmap[idx] != NULL)) {
redraw_meters(idx, widget->allocation.width, widget->allocation.height, l1, l2);
gdk_draw_pixmap(widget->window,
widget->style->black_gc,
pixmap[idx],
0, 0,
0, 0,
widget->allocation.width, widget->allocation.height);
}
update_meter(idx);
}
}
for (idx = MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + 1; idx <= input_channels + MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS; idx++) {
get_levels(idx, &l1, &l2);
widget = idx == 0 ? mixer_mix_drawing : mixer_drawing[idx-1];
if (GTK_WIDGET_VISIBLE(widget) && (pixmap[idx] != NULL)) {
redraw_meters(idx, widget->allocation.width, widget->allocation.height, l1, l2);
gdk_draw_pixmap(widget->window,
widget->style->black_gc,
pixmap[idx],
0, 0,
0, 0,
widget->allocation.width, widget->allocation.height);
}
update_meter(idx);
}
for (idx = MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS + 1; \
idx <= spdif_channels + MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS; idx++) {
get_levels(idx, &l1, &l2);
widget = idx == 0 ? mixer_mix_drawing : mixer_drawing[idx-1];
if (GTK_WIDGET_VISIBLE(widget) && (pixmap[idx] != NULL)) {
redraw_meters(idx, widget->allocation.width, widget->allocation.height, l1, l2);
gdk_draw_pixmap(widget->window,
widget->style->black_gc,
pixmap[idx],
0, 0,
0, 0,
widget->allocation.width, widget->allocation.height);
}
update_meter(idx);
}
return TRUE;
}
@ -270,6 +256,13 @@ void level_meters_init(void)
/* older ALSA driver, using MIXER type */
snd_ctl_elem_value_set_interface(peaks,
SND_CTL_ELEM_IFACE_MIXER);
penGreenShadow = get_pen(0, 0x77ff, 0);
penGreenLight = get_pen(0, 0xffff, 0);
penOrangeShadow = get_pen(0xddff, 0x55ff, 0);
penOrangeLight = get_pen(0xffff, 0x99ff, 0);
penRedShadow = get_pen(0xaaff, 0, 0);
penRedLight = get_pen(0xffff, 0, 0);
}
void level_meters_postinit(void)

View file

@ -243,7 +243,7 @@ int midi_init(char *appname, int channel, int midi_enhanced)
void mixer_adjust(GtkAdjustment *adj, gpointer data);
void mixer_set_mute(int stream, int left, int right);
void midi_process(gpointer data, gint source, GdkInputCondition condition)
gboolean midi_process(GIOChannel *gio, GIOCondition condition, gpointer data)
{
snd_seq_event_t *ev;
static GtkAdjustment *adj=0;
@ -306,6 +306,7 @@ void midi_process(gpointer data, gint source, GdkInputCondition condition)
snd_seq_free_event(ev);
}
while (snd_seq_event_input_pending(seq, 0) > 0);
return TRUE;
}
/* ************************************************* */

View file

@ -7,7 +7,7 @@ int midi_init(char *appname, int channel, int midi_enhanced);
int midi_close();
void midi_maxstreams(int);
int midi_controller(int c, int v);
void midi_process(gpointer data, gint source, GdkInputCondition condition);
gboolean midi_process(GIOChannel *gio, GIOCondition condition, gpointer data);
int midi_button(int b, int v);
#endif

View file

@ -39,7 +39,7 @@ extern int input_channels, output_channels, pcm_output_channels, spdif_channels,
static int is_active(GtkWidget *widget)
{
return GTK_TOGGLE_BUTTON(widget)->active ? 1 : 0;
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? 1 : 0;
}
void mixer_update_stream(int stream, int vol_flag, int sw_flag)
@ -181,10 +181,10 @@ void mixer_adjust(GtkAdjustment *adj, gpointer data)
int stereo = is_active(mixer_stereo_toggle[stream-1]) ? 1 : 0;
int vol[2] = { -1, -1 };
vol[button] = 96 - adj->value;
vol[button] = 96 - gtk_adjustment_get_value(adj);
if (stereo) {
gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][button ^ 1]), adj->value);
vol[button ^ 1] = 96 - adj->value;
gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][button ^ 1]), gtk_adjustment_get_value(adj));
vol[button ^ 1] = 96 - gtk_adjustment_get_value(adj);
}
set_volume1(stream, vol[0], vol[1]);
}

View file

@ -20,9 +20,9 @@ int new_process(char * const cmd_line[MAX_PARAM])
struct stat file_status;
/* memory for storage of function pointers from the signal handling routines */
void (*int_stat)();
void (*quit_stat)();
void (*usr2_stat)();
void (*int_stat)(int);
void (*quit_stat)(int);
void (*usr2_stat)(int);
/*
* check command file

View file

@ -30,7 +30,7 @@ extern int output_channels, input_channels, pcm_output_channels, spdif_channels;
static int is_active(GtkWidget *widget)
{
return GTK_TOGGLE_BUTTON(widget)->active ? 1 : 0;
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ? 1 : 0;
}
static int get_toggle_index(int stream)

View file

@ -54,9 +54,9 @@ void subst_tilde_in_filename(char * const filename)
if ((pos_after_tilde = strchr(filename, '~')) != NULL) {
pos_after_tilde++;
strncpy(new_filename, getenv("HOME"), MAX_FILE_NAME_LENGTH);
strncpy(new_filename + strlen(new_filename), pos_after_tilde, MAX_FILE_NAME_LENGTH - strlen(new_filename));
new_filename[MAX_FILE_NAME_LENGTH - 1] = '\0';
strncpy(new_filename, getenv("HOME"), sizeof(new_filename) - 1);
strncpy(new_filename + strlen(new_filename), pos_after_tilde, sizeof(new_filename) - strlen(new_filename) - 1);
new_filename[sizeof(new_filename) - 1] = '\0';
strncpy(filename, new_filename, MAX_FILE_NAME_LENGTH);
}
}
@ -78,7 +78,9 @@ int which_cfgfile(char ** const cfgfile)
(inputFile = fopen(SYS_PROFILERC, "r")) == NULL) {
res = -ENOENT;
} else {
fclose(inputFile);
if (inputFile != NULL) {
fclose(inputFile);
}
*cfgfile = SYS_PROFILERC;
res = EXIT_SUCCESS;
}
@ -94,7 +96,9 @@ int get_file_size(const char * const filename)
{
struct stat file_status;
strncpy(filename_without_tilde, filename, MAX_FILE_NAME_LENGTH);
if (filename_without_tilde != filename) {
strncpy(filename_without_tilde, filename, MAX_FILE_NAME_LENGTH);
}
filename_without_tilde[MAX_FILE_NAME_LENGTH - 1] = '\0';
subst_tilde_in_filename(filename_without_tilde);
if (stat(filename_without_tilde, &file_status) < 0) {
@ -470,7 +474,8 @@ int get_pos_name_header_from_card(const char * const buffer, const int profile_n
char place_holder;
int pos_card_begin, pos_card_end, pos_name_header;
pos_card_begin = get_card_begin(buffer, profile_number, card_number);
if ((pos_card_begin = get_card_begin(buffer, profile_number, card_number)) < 0)
return pos_card_begin;
pos_card_end = get_card_end(buffer, profile_number, card_number);
place_holder = PLACE_HOLDER_STR;
strncpy(header, PROFILE_NAME_TEMPL, MAX_SEARCH_FIELD_LENGTH);
@ -522,7 +527,7 @@ int reorganize_profiles(char * const buffer, const int max_length)
{
int profile_number, card_number, card_number_max;
int res;
int pos_profile_begin, pos_profile_end, pos_card_begin, pos_card_end, pos_name_header;
int pos_profile_begin, pos_card_begin, pos_card_end, pos_name_header;
int pos_alsa_section_begin, pos_after_alsa_section;
char header[MAX_SEARCH_FIELD_LENGTH];
void *buffer_copy = NULL;
@ -547,7 +552,6 @@ int reorganize_profiles(char * const buffer, const int max_length)
compose_search_string(header, PROFILE_HEADER_TEMPL, profile_or_card_number_as_str, place_holder, MAX_SEARCH_FIELD_LENGTH);
header[MAX_SEARCH_FIELD_LENGTH - 1] = '\0';
snprintf(buffer_copy + strlen(buffer_copy), max_length - strlen(buffer_copy), "%s\n", header);
pos_profile_end = get_profile_end(buffer, profile_number);
/* search max card number in profile */
card_number_max = get_max_card_number_in_profile(buffer, profile_number);
for (card_number = 0; card_number <= card_number_max; card_number++)
@ -641,9 +645,9 @@ int save_restore_alsactl_settings(char * const tmpfile, const int card_number, c
void compose_tmpfile_name(char * const tmpfile, const char * const cfgfile)
{
strncpy(tmpfile, cfgfile, MAX_FILE_NAME_LENGTH);
strncpy(tmpfile, cfgfile, MAX_FILE_NAME_LENGTH - 1);
tmpfile[MAX_FILE_NAME_LENGTH - 1] = '\0';
strncpy(tmpfile + strlen(tmpfile), "_alsactl_tmp", MAX_FILE_NAME_LENGTH - strlen(tmpfile));
strncpy(tmpfile + strlen(tmpfile), "_alsactl_tmp", MAX_FILE_NAME_LENGTH - strlen(tmpfile) - 1);
tmpfile[MAX_FILE_NAME_LENGTH - 1] = '\0';
}
@ -1145,13 +1149,16 @@ int save_restore(const char * const operation, const int profile_number, const i
fprintf(stderr, "Cannot save settings for card '%d' in profile '%d'.\n", card_number, profile_number);
return -errno;
}
close(res);
unlink(cfgfile);
} else {
close(res);
if ((res = open(cfgfile, O_RDWR | 0400000 /* O_NOFOLLOW */, FILE_CREA_MODE)) < 0) {
fprintf(stderr, "Cannot open configuration file '%s' for writing.\n", cfgfile);
fprintf(stderr, "Cannot save settings for card '%d' in profile '%d'.\n", card_number, profile_number);
return -errno;
}
close(res);
}
res = save_profile(profile_number, card_number, profile_name, cfgfile);
} else if (!strcmp(operation, ALSACTL_OP_RESTORE)) {

View file

@ -44,7 +44,7 @@
#define MAX_PROFILE_SIZE 32768
#define MAX_SEARCH_FIELD_LENGTH 1024
#define MAX_FILE_NAME_LENGTH 1024
#define MAX_NUM_STR_LENGTH 10
#define MAX_NUM_STR_LENGTH 11
#define TOKEN_SEP "|"
#define SEP_CHAR ' '

View file

@ -48,6 +48,7 @@ int strstr_icase_blank(const char * const string1, const char * const string2)
char search_string[MAX_SEARCH_FIELD_LENGTH];
char *pstr;
int pos_first_non_blank;
size_t len;
strncpy(search_string, string2, MAX_SEARCH_FIELD_LENGTH);
search_string[MAX_SEARCH_FIELD_LENGTH - 1] = '\0';
@ -84,7 +85,11 @@ int strstr_icase_blank(const char * const string1, const char * const string2)
}
}
}
strncpy(search_string, cmp_line, strlen(search_string));
len = strlen(search_string);
if (len > sizeof(search_string) - 1)
len = sizeof(search_string) - 1;
strncpy(search_string, cmp_line, len);
search_string[len] = '\0';
position = 0;
while (position < strlen(string1))

View file

@ -217,7 +217,7 @@ void dac_volume_adjust(GtkAdjustment *adj, gpointer data)
{
int idx = (int)(long)data;
snd_ctl_elem_value_t *val;
int err, ival = -(int)adj->value;
int err, ival = -(int)gtk_adjustment_get_value(adj);
char text[16];
snd_ctl_elem_value_alloca(&val);
@ -235,7 +235,7 @@ void adc_volume_adjust(GtkAdjustment *adj, gpointer data)
{
int idx = (int)(long)data;
snd_ctl_elem_value_t *val;
int err, ival = -(int)adj->value;
int err, ival = -(int)gtk_adjustment_get_value(adj);
char text[16];
snd_ctl_elem_value_alloca(&val);
@ -253,7 +253,7 @@ void ipga_volume_adjust(GtkAdjustment *adj, gpointer data)
{
int idx = (int)(long)data;
snd_ctl_elem_value_t *val;
int err, ival = -(int)adj->value;
int err, ival = -(int)gtk_adjustment_get_value(adj);
char text[16];
snd_ctl_elem_value_alloca(&val);

View file

@ -51,4 +51,4 @@ This is for the experts only. It makes you select each configuration field indiv
http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf )
* Parser hints
This enables you to send special "hints" to the driver that causes parsing to behave differently. Leave them at the "default" setting unless you have read the driver documentation. ( Which, at the time of this writing, is available here: https://www.kernel.org/doc/Documentation/sound/alsa/HD-Audio.txt - see the "Hint strings" section. )
This enables you to send special "hints" to the driver that causes parsing to behave differently. Leave them at the "default" setting unless you have read the driver documentation. ( Which, at the time of this writing, is available here: https://www.kernel.org/doc/Documentation/sound/hd-audio/notes.rst - see the "Hint strings" section. )

View file

@ -15,6 +15,15 @@ static gchar* tempdir = NULL;
static gchar* scriptfile = NULL;
static gchar* errorfile = NULL;
struct soundserver {
enum {
PULSEAUDIO,
PIPEWIRE
} type;
gboolean was_killed;
gchar *user;
};
static GQuark quark()
{
return g_quark_from_static_string("hda-jack-retask-error");
@ -125,33 +134,73 @@ static gchar* get_pulseaudio_client_conf()
return fname;
}
static gboolean kill_pulseaudio(gboolean* was_killed, int card, GError** err)
static gboolean call_systemctl(gchar* user, gchar* operation, gchar *unit, GError **err)
{
gchar* s;
gboolean ok;
if (getuid() == 0) {
// special case for root
// XDG_RUNTIME_DIR setup seems to be mandatory for Fedora, may differ for other distros
s = g_strdup_printf("runuser -l %s -c 'XDG_RUNTIME_DIR=/var/run/user/$(id -u) systemctl --user %s %s'", user, operation, unit);
} else {
s = g_strdup_printf("systemctl --user %s %s", operation, unit);
}
ok = g_spawn_command_line_sync(s, NULL, NULL, NULL, err);
g_free(s);
return ok;
}
static gboolean kill_soundserver(struct soundserver* state, int card, GError** err)
{
gchar* fuser = NULL, *fuser2 = NULL;
gchar* s = NULL;
gchar* clientconf = NULL;
gboolean ok;
*was_killed = FALSE;
char *p;
state->type = PULSEAUDIO;
state->was_killed = FALSE;
state->user = NULL;
/* Is PA having a lock on the sound card? */
s = g_strdup_printf("fuser -v /dev/snd/controlC%d", card);
/* Due to some bug in fuser, stdout and stderr output is unclear. Better check both. */
if (!(ok = g_spawn_command_line_sync(s, &fuser, &fuser2, NULL, err)))
goto cleanup;
if ((ok = strstr(fuser, "pulseaudio") == NULL && strstr(fuser2, "pulseaudio") == NULL))
goto cleanup; // PulseAudio not locking the sound card
if (strstr(fuser, "pulseaudio") != NULL || strstr(fuser2, "pulseaudio") != NULL) {
clientconf = get_pulseaudio_client_conf();
if (!(ok = !g_file_test(clientconf, G_FILE_TEST_EXISTS))) {
g_set_error(err, quark(), 0, "Cannot block PulseAudio from respawning:\n"
"Please either remove '%s' or kill PulseAudio manually.", clientconf);
goto cleanup;
}
if (!(ok = g_file_set_contents(clientconf, "autospawn=no\n", -1, err)))
goto cleanup;
state->was_killed = TRUE;
ok = g_spawn_command_line_sync("pulseaudio -k", NULL, NULL, NULL, err);
} else if ((p = strstr(fuser, "wireplumber")) != NULL || (p = strstr(fuser2, "wireplumber")) != NULL) {
*p = '\0';
while (p != fuser && p != fuser2 && *p != '\n')
p--;
if (*p == '\n')
p++;
GRegex *regex;
GMatchInfo *match_info;
clientconf = get_pulseaudio_client_conf();
if (!(ok = !g_file_test(clientconf, G_FILE_TEST_EXISTS))) {
g_set_error(err, quark(), 0, "Cannot block PulseAudio from respawning:\n"
"Please either remove '%s' or kill PulseAudio manually.", clientconf);
goto cleanup;
regex = g_regex_new (" ([a-zA-Z0-9_-]+) ", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
g_regex_match (regex, p, 0, &match_info);
if (g_match_info_matches (match_info))
state->user = g_match_info_fetch (match_info, 1);
g_match_info_free (match_info);
g_regex_unref (regex);
state->type = PIPEWIRE;
ok = call_systemctl(state->user, "stop", "wireplumber.service", err);
state->was_killed = ok;
} else {
// Sound server not locking the sound card
}
if (!(ok = g_file_set_contents(clientconf, "autospawn=no\n", -1, err)))
goto cleanup;
*was_killed = TRUE;
ok = g_spawn_command_line_sync("pulseaudio -k", NULL, NULL, NULL, err);
cleanup:
g_free(clientconf);
@ -161,16 +210,34 @@ cleanup:
return ok;
}
static gboolean restore_pulseaudio(gboolean was_killed, GError** err)
static gboolean restore_soundserver(struct soundserver* state, GError** err)
{
gchar* clientconf = get_pulseaudio_client_conf();
if (was_killed && g_unlink(clientconf) != 0) {
g_set_error(err, quark(), 0, "%s", g_strerror(errno));
g_free(clientconf);
return FALSE;
gboolean ok = FALSE;
gchar* clientconf;
switch (state->type) {
case PULSEAUDIO:
clientconf = get_pulseaudio_client_conf();
if (state->was_killed && g_unlink(clientconf) != 0) {
g_set_error(err, quark(), 0, "%s", g_strerror(errno));
g_free(clientconf);
goto cleanup;
}
g_free(clientconf);
ok = TRUE;
break;
case PIPEWIRE:
if (state->was_killed)
ok = call_systemctl(state->user, "start", "wireplumber.service", err);
else
ok = TRUE;
break;
}
g_free(clientconf);
return TRUE;
cleanup:
g_free(state->user);
state->user = NULL;
return ok;
}
gboolean apply_changes_reconfig(pin_configs_t* pins, int entries, int card, int device,
@ -178,10 +245,10 @@ gboolean apply_changes_reconfig(pin_configs_t* pins, int entries, int card, int
{
gboolean result = FALSE;
// gchar* script_name = NULL;
gboolean pa_killed = FALSE;
struct soundserver state = { 0 };
/* Check for users of the sound card */
/* Kill pulseaudio if necessary (and possible) */
if (!kill_pulseaudio(&pa_killed, card, err))
if (!kill_soundserver(&state, card, err))
goto cleanup;
/* Create script */
if (!create_reconfig_script(pins, entries, card, device, model, hints, err))
@ -191,7 +258,7 @@ gboolean apply_changes_reconfig(pin_configs_t* pins, int entries, int card, int
goto cleanup;
result = TRUE;
cleanup:
if (!restore_pulseaudio(pa_killed, result ? err : NULL)) {
if (!restore_soundserver(&state, result ? err : NULL)) {
result = FALSE;
}
// g_free(script_name);

View file

@ -9,7 +9,7 @@ gboolean apply_changes_reconfig(pin_configs_t* pins, int entries, int card, int
gboolean apply_changes_boot(pin_configs_t* pins, int entries, int card, int device,
const char* model, const char* hints, GError** err);
gboolean reset_changes_boot();
gboolean reset_changes_boot(GError ** err);
#endif

View file

@ -519,7 +519,7 @@ static void documentation_clicked(GtkWidget* sender, ui_data_t* ui)
int neww = screen ? (gdk_screen_get_width(screen)*3)/4 : 800;
int newh = screen ? (gdk_screen_get_height(screen)*3)/4 : 600;
gtk_window_set_default_size(GTK_WINDOW(dlg), neww, newh);
gtk_window_set_default_size(GTK_WINDOW(dlg), MIN(1600, neww), MIN(1000, newh));
}
gtk_dialog_run(dlg);

View file

@ -32,7 +32,7 @@ public:
HC_AboutText(int x, int y, int w, int h);
void draw();
private:
char *text;
const char *text;
};
#endif

View file

@ -21,7 +21,7 @@
#pragma implementation
#include "HC_Aeb.h"
static void setAebStatus(char *ctl_name, int val, int card_index)
static void setAebStatus(const char *ctl_name, int val, int card_index)
{
int err;
char card_name[6];

View file

@ -21,7 +21,7 @@
#pragma implementation
#include "HC_SpdifOut.h"
static void setSpdifBit(char *ctl_name, int val, int card_index)
static void setSpdifBit(const char *ctl_name, int val, int card_index)
{
int err;
char card_name[6];

View file

@ -51,7 +51,7 @@ public:
void setAdatSyncStatus(unsigned char s);
void setWCStatus(unsigned char s);
private:
char *adat_name;
const char *adat_name;
int h_step;
Fl_Box_Draw_F *draw_box;
};

View file

@ -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.."};

View file

@ -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++.",
"...................................."};

View file

@ -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++.",
"...................................."};

View file

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

View file

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

View file

@ -0,0 +1,133 @@
/*
* HDSPMixer
*
* Copyright (C) 2003 Thomas Charbonnel (thomas@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);
}
}

View file

@ -0,0 +1,48 @@
/*
* HDSPMixer
*
* Copyright (C) 2003 Thomas Charbonnel (thomas@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

View file

@ -93,7 +93,7 @@ static char const *labels_aio_ss_input[18] = {
"AES.L", "AES.R",
"A 1", "A 2", "A 3", "A 4",
"A 5", "A 6", "A 7", "A 8",
"AEB 1", "AEB 2", "AEB 3," "AEB 4"
"AEB 1", "AEB 2", "AEB 3", "AEB 4"
};
static char const *labels_aio_ss_playback[20] = {
@ -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();
}

View file

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

View file

@ -26,6 +26,7 @@ class HDSPMixerOutputData
{
public:
int fader_pos;
int loopback;
HDSPMixerOutputData();
};

View file

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

View file

@ -36,5 +36,6 @@ HDSPMixerPresetData::HDSPMixerPresetData()
over = 3;
level = 0;
rate = 1;
loopback = 0;
}

View file

@ -38,6 +38,7 @@ public:
int over;
int rate;
int rmsplus3;
int loopback;
HDSPMixerPresetData();
};

View file

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

View file

@ -35,8 +35,8 @@ static void readregisters_cb(void *arg)
hdsp_peak_rms_t hdsp_peak_rms;
struct hdspm_peak_rms hdspm_peak_rms;
bool isMADI = false;
uint32_t *input_peaks, *playback_peaks, *output_peaks;
uint64_t *input_rms, *playback_rms, *output_rms;
__u32 *input_peaks, *playback_peaks, *output_peaks;
__u64 *input_rms, *playback_rms, *output_rms;
HDSPMixerWindow *w = (HDSPMixerWindow *)arg;
@ -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 *in,*out;
FILE *file;
/* 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 ((file = fopen(file_name, "w")) == NULL) {
fl_alert("Error opening file %s for saving", file_name);
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,145 @@ 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);
/* 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
* 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;
}
@ -489,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;
@ -617,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();
@ -814,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;
@ -1021,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 */

View file

@ -15,6 +15,8 @@ hdspmixer_SOURCES = \
HDSPMixerEmpty.h \
HDSPMixerOutput.cxx \
HDSPMixerOutput.h \
HDSPMixerLoopback.cxx \
HDSPMixerLoopback.h \
HDSPMixerIOMixer.cxx \
HDSPMixerIOMixer.h \
HDSPMixerSelector.cxx \

View file

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

View file

@ -39,7 +39,7 @@ int main(int argc, char **argv)
{
HDSPMixerWindow *window;
HDSPMixerCard *hdsp_cards[3];
char *name, *shortname;
char *name = NULL, *shortname;
int card;
int cards = 0;

View file

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

View file

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

View file

@ -8,7 +8,8 @@ that use hardware mixing, i.e., those based on the following chips:
* Yamaha DS-1 (YMF-724/740/744/754) (driver: snd-ymfpci)
This tool requires Python, pygtk, and alsa-pyton 1.0.22 or later.
This tool requires Python, PyGObject, GTK+ 3.0 or later, and alsa-python 1.0.22
or later.
It is recommended to use at least Linux kernel 2.6.32 or alsa-driver 1.0.22;
otherwise, the name of the program that is using a stream cannot be shown.

View file

@ -1,7 +1,8 @@
#!/usr/bin/python2
#!/usr/bin/env python
# hwmixvolume - ALSA hardware mixer volume control applet
# Copyright (c) 2009-2010 Clemens Ladisch
# Copyright (c) 2018 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@ -15,7 +16,10 @@
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
import gobject, gtk
import gi
gi.require_version('GLib', '2.0')
gi.require_version('Gtk', '3.0')
from gi.repository import GLib, Gtk
from pyalsa import alsacard, alsahcontrol
INTF_PCM = alsahcontrol.interface_id['PCM']
@ -26,285 +30,283 @@ EVENT_INFO = alsahcontrol.event_mask['INFO']
EVENT_REMOVE = alsahcontrol.event_mask_remove
class Stream:
def __init__(self, element, parent):
self.element = element
self.element.set_callback(self)
self.parent = parent
self.label = None
self.scales = []
self.adjustments = []
self.callback(self.element, EVENT_INFO)
def __init__(self, element, parent):
self.element = element
self.element.set_callback(self)
self.parent = parent
self.label = None
self.scales = []
self.adjustments = []
self.callback(self.element, EVENT_INFO)
def destroy(self):
self.deactivate()
def destroy(self):
self.deactivate()
def callback(self, e, mask):
if mask == EVENT_REMOVE:
self.deactivate()
elif (mask & EVENT_INFO) != 0:
info = alsahcontrol.Info(self.element)
if info.is_inactive:
self.deactivate()
else:
self.activate()
elif (mask & EVENT_VALUE) != 0:
self.update_scales_from_ctl()
def callback(self, e, mask):
if mask == EVENT_REMOVE:
self.deactivate()
elif (mask & EVENT_INFO) != 0:
info = alsahcontrol.Info(self.element)
if info.is_inactive:
self.deactivate()
else:
self.activate()
elif (mask & EVENT_VALUE) != 0:
self.update_scales_from_ctl()
def activate(self):
if self.label:
return
info = alsahcontrol.Info(self.element)
value = alsahcontrol.Value(self.element)
value.read()
values = value.get_tuple(TYPE_INTEGER, info.count)
self.label = gtk.Label(self.get_label(info))
self.label.set_single_line_mode(True)
self.parent.scales_vbox.pack_start(self.label, expand=False)
for i in range(info.count):
adj = gtk.Adjustment(value=values[i],
lower=info.min, upper=info.max,
step_incr=1,
page_incr=(info.max-info.min+1)/8)
adj.connect('value-changed', self.update_ctl_from_scale, i)
scale = gtk.HScale(adj)
scale.set_draw_value(False)
self.parent.scales_vbox.pack_start(scale, expand=False)
self.scales.append(scale)
self.adjustments.append(adj)
self.parent.scales_vbox.show_all()
self.parent.update_msg_label()
def activate(self):
if self.label:
return
info = alsahcontrol.Info(self.element)
value = alsahcontrol.Value(self.element)
value.read()
values = value.get_tuple(TYPE_INTEGER, info.count)
self.label = Gtk.Label.new(self.get_label(info))
self.label.set_single_line_mode(True)
self.parent.scales_vbox.add(self.label)
for i in range(info.count):
adj = Gtk.Adjustment(value=values[i],
lower=info.min, upper=info.max,
step_incr=1,
page_incr=(info.max-info.min+1)/8)
adj.connect('value-changed', self.update_ctl_from_scale, i)
scale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=adj)
scale.set_draw_value(False)
self.parent.scales_vbox.add(scale)
self.scales.append(scale)
self.adjustments.append(adj)
self.parent.scales_vbox.show_all()
self.parent.update_msg_label()
def deactivate(self):
if not self.label:
return
self.label.destroy()
for s in self.scales:
s.destroy()
self.label = None
self.scales = []
self.adjustments = []
self.parent.update_msg_label()
def deactivate(self):
if not self.label:
return
self.label.destroy()
for s in self.scales:
s.destroy()
self.label = None
self.scales = []
self.adjustments = []
self.parent.update_msg_label()
def update_scales_from_ctl(self):
if not self.label:
return
count = len(self.adjustments)
value = alsahcontrol.Value(self.element)
value.read()
values = value.get_tuple(TYPE_INTEGER, count)
for i in range(count):
self.adjustments[i].set_value(values[i])
def update_scales_from_ctl(self):
if not self.label:
return
count = len(self.adjustments)
value = alsahcontrol.Value(self.element)
value.read()
values = value.get_tuple(TYPE_INTEGER, count)
for i in range(count):
self.adjustments[i].set_value(values[i])
def update_ctl_from_scale(self, adj, index):
scale_value = adj.get_value()
value_to_set = int(round(adj.get_value()))
count = len(self.adjustments)
value = alsahcontrol.Value(self.element)
if self.parent.lock_check.get_active():
values = [value_to_set for i in range(count)]
else:
value.read()
values = value.get_array(TYPE_INTEGER, count)
values[index] = value_to_set
value.set_array(TYPE_INTEGER, values)
value.write()
if value_to_set != scale_value:
adj.set_value(value_to_set)
def update_ctl_from_scale(self, adj, index):
scale_value = adj.get_value()
value_to_set = int(round(adj.get_value()))
count = len(self.adjustments)
value = alsahcontrol.Value(self.element)
if self.parent.lock_check.get_active():
values = [value_to_set for i in range(count)]
else:
value.read()
values = value.get_array(TYPE_INTEGER, count)
values[index] = value_to_set
value.set_array(TYPE_INTEGER, values)
value.write()
if value_to_set != scale_value:
adj.set_value(value_to_set)
def get_label(self, info):
pid = self.get_pid(info)
if pid:
cmdline = self.get_pid_cmdline(pid)
if cmdline:
return cmdline
else:
return "PID %d" % pid
else:
name = info.name
if name[-7:] == " Volume":
name = name[:-7]
if name[-9:] == " Playback":
name = name[:-9]
return name
def get_label(self, info):
pid = self.get_pid(info)
if pid:
cmdline = self.get_pid_cmdline(pid)
if cmdline:
return cmdline
else:
return "PID %d" % pid
else:
name = info.name
if name[-7:] == " Volume":
name = name[:-7]
if name[-9:] == " Playback":
name = name[:-9]
return name
def get_pid(self, info):
card = self.parent.current_card
device = info.device
subdevice = info.subdevice
if subdevice == 0:
subdevice = info.index
filename = "/proc/asound/card%d/pcm%dp/sub%d/status" % (card, device, subdevice)
try:
f = open(filename, "r")
except IOError:
return None
try:
for line in f.readlines():
if line[:9] == "owner_pid":
return int(line.split(':')[1].strip())
finally:
f.close()
return None
def get_pid(self, info):
card = self.parent.current_card
device = info.device
subdevice = info.subdevice
if subdevice == 0:
subdevice = info.index
filename = "/proc/asound/card%d/pcm%dp/sub%d/status" % (card, device, subdevice)
try:
with open(filename, "r") as f:
for line in f:
if line[:9] == "owner_pid":
return int(line.split(':')[1].strip())
except IOError:
return None
return None
def get_pid_cmdline(self, pid):
try:
f = open("/proc/%d/cmdline" % pid, "r")
except IOError:
return None
try:
cmdline = f.read()
finally:
f.close()
return cmdline.replace('\x00', ' ').strip()
def get_pid_cmdline(self, pid):
try:
with open("/proc/%d/cmdline" % pid, "r") as f:
cmdline = f.read()
except IOError:
return None
return cmdline.replace('\x00', ' ').strip()
class MixerWindow(gtk.Window):
card_numbers = alsacard.card_list()
current_card = -1
hcontrol = None
scales_vbox = None
msg_label = None
streams = []
hctl_sources = []
class MixerWindow(Gtk.Window):
card_numbers = alsacard.card_list()
current_card = -1
hcontrol = None
scales_vbox = None
msg_label = None
streams = []
hctl_sources = []
def __init__(self):
gtk.Window.__init__(self)
self.connect('destroy', lambda w: gtk.main_quit())
self.set_title("Hardware Mixer Volumes")
def __init__(self):
Gtk.Window.__init__(self)
self.connect('destroy', lambda w: Gtk.main_quit())
self.set_title("Hardware Mixer Volumes")
vbox = gtk.VBox()
self.add(vbox)
vbox = Gtk.Grid()
vbox.set_orientation(Gtk.Orientation.VERTICAL)
self.add(vbox)
hbox = gtk.HBox()
vbox.pack_start(hbox, expand=False)
hbox = Gtk.Grid()
vbox.add(hbox)
label = gtk.Label("_Sound Card: ")
label.set_use_underline(True)
hbox.pack_start(label, expand=False)
label = Gtk.Label.new_with_mnemonic("_Sound Card: ")
hbox.add(label)
combo = gtk.combo_box_new_text()
for i in self.card_numbers:
str = "%d: %s" % (i, alsacard.card_get_name(i))
combo.append_text(str)
if len(self.card_numbers) > 0:
combo.set_active(0)
combo.connect('changed', lambda c: self.change_card(self.card_numbers[combo.get_active()]))
hbox.pack_start(combo)
label.set_mnemonic_widget(combo)
combo = Gtk.ComboBoxText()
combo.set_hexpand(True)
for i in self.card_numbers:
str = "%d: %s" % (i, alsacard.card_get_name(i))
combo.append_text(str)
if len(self.card_numbers) > 0:
combo.set_active(0)
combo.connect('changed', lambda c: self.change_card(self.card_numbers[combo.get_active()]))
hbox.add(combo)
label.set_mnemonic_widget(combo)
self.lock_check = gtk.CheckButton(label="_Lock Channels")
self.lock_check.set_active(True)
vbox.pack_start(self.lock_check, expand=False)
self.lock_check = Gtk.CheckButton.new_with_mnemonic(label="_Lock Channels")
self.lock_check.set_active(True)
vbox.add(self.lock_check)
scrollwin = gtk.ScrolledWindow()
scrollwin.set_policy(hscrollbar_policy=gtk.POLICY_NEVER, vscrollbar_policy=gtk.POLICY_AUTOMATIC)
scrollwin.set_shadow_type(gtk.SHADOW_NONE)
vbox.pack_start(scrollwin)
scrollwin = Gtk.ScrolledWindow()
scrollwin.set_policy(hscrollbar_policy=Gtk.PolicyType.NEVER, vscrollbar_policy=Gtk.PolicyType.AUTOMATIC)
scrollwin.set_shadow_type(Gtk.ShadowType.NONE)
scrollwin.set_vexpand(True)
vbox.add(scrollwin)
self.scales_vbox = gtk.VBox()
scrollwin.add_with_viewport(self.scales_vbox)
self.scales_vbox = Gtk.Grid()
self.scales_vbox.set_orientation(Gtk.Orientation.VERTICAL)
scrollwin.add(self.scales_vbox)
label = gtk.Label()
label.set_single_line_mode(True)
line_height = label.size_request()[1]
label.destroy()
scale = gtk.HScale()
scale.set_draw_value(False)
line_height += scale.size_request()[1]
scale.destroy()
# always have space for at least four sliders
scrollwin.set_size_request(width=-1, height=line_height*4+4)
label = Gtk.Label()
label.set_single_line_mode(True)
line_height = max(label.get_size_request().height, 0)
label.destroy()
scale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL)
scale.set_draw_value(False)
line_height += max(scale.get_size_request().height, 0)
scale.destroy()
# always have space for at least four sliders
scrollwin.set_size_request(width=-1, height=line_height*4+4)
# TODO: select the default card or the first card with stream controls
if len(self.card_numbers) > 0:
self.change_card(self.card_numbers[0])
self.update_msg_label()
# TODO: select the default card or the first card with stream controls
if len(self.card_numbers) > 0:
self.change_card(self.card_numbers[0])
self.update_msg_label()
self.show_all()
self.show_all()
def change_card(self, cardnum):
for s in self.hctl_sources:
gobject.source_remove(s)
self.hctl_sources = []
def change_card(self, cardnum):
for s in self.hctl_sources:
GLib.source_remove(s)
self.hctl_sources = []
self.hcontrol = self.open_hcontrol_for_card(cardnum)
self.hcontrol = self.open_hcontrol_for_card(cardnum)
for s in self.streams:
s.destroy()
self.streams = []
for s in self.streams:
s.destroy()
self.streams = []
self.current_card = cardnum
self.current_card = cardnum
if not self.hcontrol:
self.update_msg_label()
return
if not self.hcontrol:
self.update_msg_label()
return
for id in self.hcontrol.list():
if not self.is_stream_elem(id):
continue
elem = alsahcontrol.Element(self.hcontrol, id[0])
info = alsahcontrol.Info(elem)
if not self.is_stream_info(info):
continue
stream = Stream(elem, self)
self.streams.append(stream)
for id in self.hcontrol.list():
if not self.is_stream_elem(id):
continue
elem = alsahcontrol.Element(self.hcontrol, id[0])
info = alsahcontrol.Info(elem)
if not self.is_stream_info(info):
continue
stream = Stream(elem, self)
self.streams.append(stream)
for fd,condition in self.hcontrol.poll_fds:
self.hctl_sources.append(gobject.io_add_watch(fd, condition, self.hctl_io_callback))
for fd,condition in self.hcontrol.poll_fds:
self.hctl_sources.append(GLib.io_add_watch(fd, 0, GLib.IOCondition(condition), self.hctl_io_callback))
self.update_msg_label()
self.update_msg_label()
self.scales_vbox.show_all()
self.scales_vbox.show_all()
def update_msg_label(self):
needs_msg = len(self.scales_vbox.get_children()) < 2
has_msg = self.msg_label
if has_msg and not needs_msg:
self.msg_label.destroy()
self.msg_label = None
elif needs_msg:
if len(self.streams) > 0:
msg = "There are no open streams."
else:
msg = "This card does not have stream controls."
if not has_msg:
self.msg_label = gtk.Label(msg)
self.scales_vbox.pack_start(self.msg_label)
self.scales_vbox.show_all()
elif self.msg_label.get_text() != msg:
self.msg_label.set_text(msg)
def update_msg_label(self):
needs_msg = len(self.scales_vbox.get_children()) < 2
has_msg = self.msg_label
if has_msg and not needs_msg:
self.msg_label.destroy()
self.msg_label = None
elif needs_msg:
if len(self.streams) > 0:
msg = "There are no open streams."
else:
msg = "This card does not have stream controls."
if not has_msg:
self.msg_label = Gtk.Label.new(msg)
self.msg_label.set_vexpand(True)
self.scales_vbox.add(self.msg_label)
self.scales_vbox.show_all()
elif self.msg_label.get_text() != msg:
self.msg_label.set_text(msg)
def open_hcontrol_for_card(self, cardnum):
devname = "hw:CARD=" + str(cardnum)
try:
hc = alsahcontrol.HControl(name=devname,
mode=alsahcontrol.open_mode['NONBLOCK'])
except:
# TODO: alsa error msg
dlg = gtk.MessageDialog(self,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
"Cannot open sound card control device.")
dlg.run()
dlg.destroy()
return None
return hc
def open_hcontrol_for_card(self, cardnum):
devname = "hw:CARD=" + str(cardnum)
try:
hc = alsahcontrol.HControl(name=devname,
mode=alsahcontrol.open_mode['NONBLOCK'])
except:
# TODO: alsa error msg
dlg = Gtk.MessageDialog(self,
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
"Cannot open sound card control device.")
dlg.run()
dlg.destroy()
return None
return hc
def is_stream_elem(self, id):
return ((id[1] == INTF_PCM and
id[4] in ("PCM Playback Volume", "EMU10K1 PCM Volume")) or
(id[1] == INTF_MIXER and
id[4] == "VIA DXS Playback Volume"))
def is_stream_elem(self, id):
return ((id[1] == INTF_PCM and
id[4] in ("PCM Playback Volume", "EMU10K1 PCM Volume")) or
(id[1] == INTF_MIXER and
id[4] == "VIA DXS Playback Volume"))
def is_stream_info(self, info):
return info.is_readable and info.is_writable and info.type == TYPE_INTEGER
def is_stream_info(self, info):
return info.is_readable and info.is_writable and info.type == TYPE_INTEGER
def hctl_io_callback(self, source, condition):
self.hcontrol.handle_events()
return True
def hctl_io_callback(self, source, condition):
self.hcontrol.handle_events()
return True
def main():
MixerWindow()
gtk.main()
MixerWindow()
Gtk.main()
main()

View file

@ -4,6 +4,7 @@ AC_CONFIG_MACRO_DIR([m4])
AM_MAINTAINER_MODE([enable])
AC_CONFIG_HEADERS(config.h)
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_PROG_LD
AC_PROG_INSTALL

View file

@ -354,7 +354,7 @@ int dump_load(int audigy, char *file_name)
fctrl = (ld10k1_ctl_dump_t *)ptr;
memset(ctrl, 0, sizeof(emu10k1_fx8010_control_gpr_t) * header->ctl_count);
for (i = 0; i < header->ctl_count; i++) {
strcpy(ctrl[i].id.name, fctrl[i].name);
strcpy((char *)ctrl[i].id.name, fctrl[i].name);
ctrl[i].id.iface = EMU10K1_CTL_ELEM_IFACE_MIXER;
ctrl[i].id.index = fctrl[i].index;
ctrl[i].vcount = fctrl[i].vcount;

View file

@ -77,7 +77,7 @@ void error(const char *fmt, ...)
va_end(va);
}
static void log(const char *fmt, ...)
static void alog(const char *fmt, ...)
{
va_list va;
@ -116,7 +116,7 @@ static void cleanup()
{
if (pidpath[0])
unlink(pidpath);
log("Exiting daemon");
alog("Exiting daemon");
}
static void term_handler(int i)
@ -247,7 +247,7 @@ int main(int argc, char *argv[])
pidfile = fopen(pidpath, "wt");
if (!pidfile) {
log("%s: pidfile (%s)\n", strerror(errno), pidpath);
alog("%s: pidfile (%s)\n", strerror(errno), pidpath);
return 1;
}
@ -263,7 +263,7 @@ int main(int argc, char *argv[])
dup2(fileno(logfile), fileno(stdout));
}
log("Starting daemon");
alog("Starting daemon");
}
params.type = uses_pipe ? COMM_TYPE_LOCAL : COMM_TYPE_IP;

View file

@ -199,7 +199,7 @@ int ld10k1_update_driver(ld10k1_dsp_mgr_t *dsp_mgr)
if (!add_ctrl)
return LD10K1_ERR_NO_MEM;
for (i = 0, item = dsp_mgr->add_ctl_list; item != NULL; item = item->next, i++) {
strcpy(add_ctrl[i].id.name, item->ctl.name);
strcpy((char *)add_ctrl[i].id.name, item->ctl.name);
add_ctrl[i].id.iface = EMU10K1_CTL_ELEM_IFACE_MIXER;
add_ctrl[i].id.index = item->ctl.index;
add_ctrl[i].vcount = item->ctl.vcount;
@ -225,7 +225,7 @@ int ld10k1_update_driver(ld10k1_dsp_mgr_t *dsp_mgr)
if (!del_ids)
return LD10K1_ERR_NO_MEM;
for (i = 0, item = dsp_mgr->del_ctl_list; item != NULL; item = item->next, i++) {
strcpy(del_ids[i].name, item->ctl.name);
strcpy((char *)del_ids[i].name, item->ctl.name);
del_ids[i].iface = EMU10K1_CTL_ELEM_IFACE_MIXER;
del_ids[i].index = item->ctl.index;
}

View file

@ -2152,7 +2152,7 @@ int ld10k1_conn_point_add(ld10k1_dsp_mgr_t *dsp_mgr, ld10k1_conn_point_t *point,
int allocgprcount = 0;
int allocinstrcount = 0;
unsigned int reserved[2];
unsigned int res[2];
int res[2];
int reservedcount = 0;
int usedreserved = 0;

View file

@ -179,7 +179,7 @@ int main_loop(comm_param *param, int audigy, const char *card_id, int tram_size,
{
fd_set active_fd_set/*, read_fd_set*/;
int i, j, res = 0;
__sighandler_t old_sig_pipe;
sighandler_t old_sig_pipe;
int main_sock = 0;
int data_sock = 0;
@ -792,12 +792,9 @@ int ld10k1_fnc_name_find(int data_conn, int op, int size)
int ld10k1_fnc_name_rename(int data_conn, int op, int size)
{
ld10k1_fnc_name_t name_info;
int ret;
int err;
ld10k1_patch_t *patch;
ret = -1;
if ((err = receive_msg_data(data_conn, &name_info, sizeof(ld10k1_fnc_name_t))) < 0)
return err;

View file

@ -473,8 +473,9 @@ static int transfer_patch(int udin, char *ctrl_opt, liblo10k1_emu_patch_t *ep, l
if (*ctrl_opt != ',') {
error("wrong ctrl option format - wrong separator beetwen subfunctions");
return 1;
} else
*ctrl_opt++;
} else {
ctrl_opt++;
}
}
}
@ -691,8 +692,9 @@ static int transfer_native_patch(liblo10k1_dsp_patch_t *p, char *ctrl_opt)
if (*ctrl_opt != ',') {
error("wrong ctrl option format - wrong separator beetwen subfunctions");
return 1;
} else
*ctrl_opt++;
} else {
ctrl_opt++;
}
}
}
@ -1466,7 +1468,6 @@ int main(int argc, char *argv[])
int opt_list;
int opt_setup;
int opt_info;
int opt_add;
int opt_del;
int opt_con_add;
@ -1526,7 +1527,6 @@ int main(int argc, char *argv[])
opt_add = 0;
opt_del = 0;
opt_list_patch = NULL;
opt_info = 0;
opt_con_add = 0;
opt_con_del = 0;
opt_debug = 0;
@ -1618,7 +1618,7 @@ int main(int argc, char *argv[])
opt_list_patch = optarg;
break;
case 'i':
opt_info = 1;
/* nothing */
break;
case 'q':
opt_con_add = 1;

View file

@ -89,7 +89,8 @@ static int get_file_name(const char *key, unsigned int idx, char *fname)
for (p = buf + len; *p && isspace(*p); p++)
;
if (*p == '/') {
strncpy(fname, p, MAX_PATH);
strncpy(fname, p, MAX_PATH - 1);
fname[MAX_PATH - 1] = '\0';
} else {
snprintf(fname, MAX_PATH, "%s/%s", DATAPATH, p);
}

View file

@ -89,7 +89,8 @@ static int get_file_name(const char *key, unsigned int idx, char *fname)
for (p = buf + len; *p && isspace(*p); p++)
;
if (*p == '/') {
strncpy(fname, p, MAX_PATH);
strncpy(fname, p, MAX_PATH - 1);
fname[MAX_PATH - 1] = '\0';
} else {
snprintf(fname, MAX_PATH, "%s/%s", DATAPATH, p);
}

View file

@ -29,7 +29,7 @@ void destroy(GtkWidget *widget,gpointer data)
int main(int argc, char *argv[])
{
int card;
char name[8],*err;
char name[16],*err;
snd_ctl_card_info_t *hw_info;
card_type_t type;

View file

@ -63,7 +63,7 @@ static void usage(void)
{
printf("Tascam US-428 Control\n");
printf("version %s\n", VERSION);
printf("usage: "PROGNAME" [-v verbosity_level 0..2] [-c card] [-D device] [-u usb-device] [-m mode]\n");
printf("usage: " PROGNAME " [-v verbosity_level 0..2] [-c card] [-D device] [-u usb-device] [-m mode]\n");
printf("mode is one of (us224, us428, mixxx)\n");
}
/*

View file

@ -225,7 +225,8 @@ static int get_file_name(const char *key, unsigned int idx, char *fname)
for (p = buf + len; *p && isspace(*p); p++)
;
if (*p == '/') {
strncpy(fname, p, MAX_PATH);
strncpy(fname, p, MAX_PATH - 1);
fname[MAX_PATH - 1] = '\0';
} else {
snprintf(fname, MAX_PATH, "%s/%s", DATAPATH, p);
}

View file

@ -214,7 +214,8 @@ static int get_file_name(const char *key, unsigned int idx, char *fname)
for (p = buf + len; *p && isspace(*p); p++)
;
if (*p == '/') {
strncpy(fname, p, MAX_PATH);
strncpy(fname, p, MAX_PATH - 1);
fname[MAX_PATH - 1] = '\0';
} else {
snprintf(fname, MAX_PATH, "%s/%s", DATAPATH, p);
}