From: Takashi Iwai Date: Mon, 6 Oct 2003 15:57:22 +0000 (+0000) Subject: added us428control utility by Karsten Wiese X-Git-Tag: v1.0.3~52 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=994603c4f9a2e837cf699e692312d585af3c88b1;p=alsa-tools.git added us428control utility by Karsten Wiese --- diff --git a/Makefile b/Makefile index 669e4d7..1b677b0 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 0.9.7 TOP = . SUBDIRS = ac3dec as10k1 envy24control hdsploader hdspconf hdspmixer \ - mixartloader rmedigicontrol sb16_csp seq sscape_ctl usx2yloader \ - vxloader + mixartloader rmedigicontrol sb16_csp seq sscape_ctl us428control \ + usx2yloader vxloader all: @for i in $(SUBDIRS); do cd $(TOP)/$$i; ./cvscompile; cd ..; make -C $$i; done diff --git a/us428control/Cus428State.cc b/us428control/Cus428State.cc new file mode 100644 index 0000000..47e8ff3 --- /dev/null +++ b/us428control/Cus428State.cc @@ -0,0 +1,83 @@ +/* + * Controller for Tascam US-X2Y + * + * Copyright (c) 2003 by Karsten Wiese + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "Cus428State.h" + +extern int verbose; + +void +us428_lights::init_us428_lights() +{ + int i = 0; + memset(this, 0, sizeof(*this)); + for (i = 0; i < 7; ++i) + Light[ i].Offset = i + 0x19; +} + +int +Cus428State::LightSend() +{ + int Next = us428ctls_sharedmem->p4outLast + 1; + if(Next < 0 || Next >= N_us428_p4out_BUFS) + Next = 0; + memcpy(&us428ctls_sharedmem->p4out[Next].lights, Light, sizeof(us428_lights)); + us428ctls_sharedmem->p4out[Next].type = eLT_Light; + return us428ctls_sharedmem->p4outLast = Next; +} + +void +Cus428State::SliderChangedTo(int S, unsigned char New) +{ + if ((S >= eFader4 || S < 0) && S != eFaderM) + return; + + usX2Y_volume V; + V.SetTo(S, New); + int Next = us428ctls_sharedmem->p4outLast + 1; + if (Next < 0 || Next >= N_us428_p4out_BUFS) + Next = 0; + memcpy(&us428ctls_sharedmem->p4out[Next].vol, &V, sizeof(V)); + us428ctls_sharedmem->p4out[Next].type = eLT_Volume; + us428ctls_sharedmem->p4outLast = Next; +} + + +void +Cus428State::KnobChangedTo(eKnobs K, bool V) +{ + switch (K) { + case eK_InputMonitor: + if (verbose > 1) + printf("Knob InputMonitor now %i", V); + if (V) { + LightSet(eL_InputMonitor, ! LightIs(eL_InputMonitor)); + LightSend(); + } + if (verbose > 1) + printf(" Light is %i\n", LightIs(eL_InputMonitor)); + break; + default: + if (verbose > 1) + printf("Knob %i now %i\n", K, V); + } +} + diff --git a/us428control/Cus428State.h b/us428control/Cus428State.h new file mode 100644 index 0000000..35c5dd6 --- /dev/null +++ b/us428control/Cus428State.h @@ -0,0 +1,48 @@ +/* + * Controller for Tascam US-X2Y + * + * Copyright (c) 2003 by Karsten Wiese + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef Cus428State_h +#define Cus428State_h + +#include "Cus428_ctls.h" + +class Cus428State: public us428_lights, public Cus428_ctls{ + public: + Cus428State(struct us428ctls_sharedmem* Pus428ctls_sharedmem) + :us428ctls_sharedmem(Pus428ctls_sharedmem) + { + init_us428_lights(); + } + enum eKnobs{ + eK_RECORD = 72, + eK_PLAY = 73, + eK_STOP, + eK_InputMonitor = 80 + }; + void KnobChangedTo(eKnobs K, bool V); + void SliderChangedTo(int S, unsigned char New); + private: + int LightSend(); + struct us428ctls_sharedmem* us428ctls_sharedmem; +}; + +extern Cus428State* OneState; + +#endif diff --git a/us428control/Cus428_ctls.cc b/us428control/Cus428_ctls.cc new file mode 100644 index 0000000..4bbe32d --- /dev/null +++ b/us428control/Cus428_ctls.cc @@ -0,0 +1,57 @@ +/* + * Controller for Tascam US-X2Y + * + * Copyright (c) 2003 by Karsten Wiese + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "Cus428_ctls.h" +#include "Cus428State.h" + +Cus428State* OneState; + +void +Cus428_ctls::dump(int n) +{ + for (int m = 0; m < n; m++) + printf(" "); + for (; n < sizeof(*this); n++) + printf("%02hhX ", ((char*)this)[ n]); + printf("\n"); +} + +void +Cus428_ctls::analyse(Cus428_ctls& Previous, unsigned n) +{ + for (; n < 9; n++) { //Sliders + char Diff = ((unsigned char*)this)[ n] - ((unsigned char*)&Previous)[ n]; + if (Diff) + OneState->SliderChangedTo(n, ((unsigned char*)this)[ n]); + } + for (; n < 16; n++) { //Knobs + unsigned char Diff = ((unsigned char*)this)[ n] ^ ((unsigned char*)&Previous)[ n]; + unsigned o = 0; + while (o < 8) { + if (Diff & (1 << o)) + OneState->KnobChangedTo((Cus428State::eKnobs)(8*n + o), ((unsigned char*)this)[ n] & (1 << o)); + ++o; + } + } + for (; n < sizeof(*this); n++) + ; //wheels +} diff --git a/us428control/Cus428_ctls.h b/us428control/Cus428_ctls.h new file mode 100644 index 0000000..71bd849 --- /dev/null +++ b/us428control/Cus428_ctls.h @@ -0,0 +1,32 @@ +/* + * Controller for Tascam US-X2Y + * + * Copyright (c) 2003 by Karsten Wiese + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef Cus428_ctls_h +#define Cus428_ctls_h +#include "usbus428ctldefs.h" + + +class Cus428_ctls: public us428_ctls{ + public: + void dump(int n = 0); + void analyse(Cus428_ctls& Previous, unsigned n = 0); +}; + +#endif diff --git a/us428control/Makefile.am b/us428control/Makefile.am new file mode 100644 index 0000000..a5765b2 --- /dev/null +++ b/us428control/Makefile.am @@ -0,0 +1,15 @@ +# # Process this file with automake to produce Makefile.in. +AUTOMAKE_OPTIONS = 1.3 foreign + +bin_PROGRAMS = us428control + +us428control_SOURCES = us428control.cc Cus428State.cc Cus428_ctls.cc +us428control_HEADERS = Cus428State.h Cus428_ctls.h usbus428ctldefs.h + +EXTRA_DIST = depcomp + +alsa-dist: distdir + @rm -rf ../distdir/us428control + @mkdir -p ../distdir/us428control + @cp -RLpv $(distdir)/* ../distdir/us428control + @rm -rf $(distdir) diff --git a/us428control/configure.in b/us428control/configure.in new file mode 100644 index 0000000..c39bfbd --- /dev/null +++ b/us428control/configure.in @@ -0,0 +1,11 @@ +AC_INIT(us428control.cc) +AM_INIT_AUTOMAKE(us428control, 0.1) +AC_PROG_CXX +AC_PROG_INSTALL +AC_HEADER_STDC +AM_PATH_ALSA(0.9.0) + +CFLAGS="$CFLAGS $ALSA_CFLAGS" +LDFLAGS="$LDFLAGS $ALSA_LIBS" + +AC_OUTPUT(Makefile) diff --git a/us428control/cvscompile b/us428control/cvscompile new file mode 100644 index 0000000..5daa701 --- /dev/null +++ b/us428control/cvscompile @@ -0,0 +1,11 @@ +#!/bin/bash + +aclocal $ACLOCAL_FLAGS +automake --foreign --add-missing +autoconf +export CFLAGS='-O2 -Wall -pipe -g' +echo "CFLAGS=$CFLAGS" +echo "./configure $@" +./configure $@ +unset CFLAGS +make diff --git a/us428control/us428control.cc b/us428control/us428control.cc new file mode 100644 index 0000000..65f130e --- /dev/null +++ b/us428control/us428control.cc @@ -0,0 +1,193 @@ +/* + * Controller for Tascam US-X2Y + * + * Copyright (c) 2003 by Karsten Wiese + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Cus428_ctls.h" +#include "Cus428State.h" + + +#define PROGNAME "us428control" +#define SND_USX2Y_LOADER_ID "USX2Y Loader" + +/* max. number of cards (shouldn't be in the public header?) */ +#define SND_CARDS 8 + +int verbose = 1; + + +static void error(const char *fmt, ...) +{ + if (verbose) { + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s: ", PROGNAME); + vfprintf(stderr, fmt, ap); + va_end(ap); + } +} + + +static void usage(void) +{ + printf("Tascam US-428 Contol\n"); + printf("version %s\n", VERSION); + printf("usage: "PROGNAME" [-v verbosity_level 0..2] [-c card] [-D device] [-u usb-device]\n"); +} +/* + * check the name id of the given hwdep handle + */ +static int check_hwinfo(snd_hwdep_t *hw, const char *id, const char* usb_dev_name) +{ + snd_hwdep_info_t *info; + int err; + + snd_hwdep_info_alloca(&info); + if ((err = snd_hwdep_info(hw, info)) < 0) + return err; + if (strcmp(snd_hwdep_info_get_id(info), id)) + return -ENODEV; + if (usb_dev_name) + if (strcmp(snd_hwdep_info_get_name(info), usb_dev_name)) + return -ENODEV; + + return 0; /* ok */ +} + +int US428Control(const char* DevName) +{ + snd_hwdep_t *hw; + int err; + unsigned int idx, dsps, loaded; + us428ctls_sharedmem_t *us428ctls_sharedmem; + struct pollfd pfds; + + if ((err = snd_hwdep_open(&hw, DevName, O_RDWR)) < 0) { + error("cannot open hwdep %s\n", DevName); + return err; + } + + if (check_hwinfo(hw, SND_USX2Y_LOADER_ID, NULL) < 0) { + error("invalid hwdep %s\n", DevName); + snd_hwdep_close(hw); + return -ENODEV; + } + snd_hwdep_poll_descriptors(hw, &pfds, 1); + us428ctls_sharedmem = (us428ctls_sharedmem_t*)mmap(NULL, sizeof(us428ctls_sharedmem_t), PROT_READ|PROT_WRITE, MAP_SHARED, pfds.fd, 0); + if (us428ctls_sharedmem == MAP_FAILED) { + perror("mmap failed:"); + return -ENOMEM; + } + us428ctls_sharedmem->CtlSnapShotRed = us428ctls_sharedmem->CtlSnapShotLast; + OneState = new Cus428State(us428ctls_sharedmem); + while (1) { + int x = poll(&pfds,1,-1); + if (verbose > 1 || pfds.revents & (POLLERR|POLLHUP)) + printf("poll returned 0x%X\n", pfds.revents); + if (pfds.revents & (POLLERR|POLLHUP)) + return -ENXIO; + int Last = us428ctls_sharedmem->CtlSnapShotLast; + if (verbose > 1) + printf("Last is %i\n", Last); + while (us428ctls_sharedmem->CtlSnapShotRed != Last) { + int Read = us428ctls_sharedmem->CtlSnapShotRed + 1; + if (Read >= N_us428_ctl_BUFS) + Read = 0; + Cus428_ctls* PCtlSnapShot = ((Cus428_ctls*)(us428ctls_sharedmem->CtlSnapShot)) + Read; + int DiffAt = us428ctls_sharedmem->CtlSnapShotDiffersAt[Read]; + if (verbose > 1) + PCtlSnapShot->dump(DiffAt); + PCtlSnapShot->analyse(((Cus428_ctls*)(us428ctls_sharedmem->CtlSnapShot))[us428ctls_sharedmem->CtlSnapShotRed], DiffAt ); + us428ctls_sharedmem->CtlSnapShotRed = Read; + } + } +} + +int main (int argc, char *argv[]) +{ + int c; + int card = -1; + char *device_name = NULL, + *usb_device_name = getenv("DEVICE"); + char name[64]; + + while ((c = getopt(argc, argv, "c:D:u:v:")) != -1) { + switch (c) { + case 'c': + card = atoi(optarg); + break; + case 'D': + device_name = optarg; + break; + case 'u': + usb_device_name = optarg; + break; + case 'v': + verbose = atoi(optarg); + break; + default: + usage(); + return 1; + } + } + + if (usb_device_name) { + snd_hwdep_t *hw = NULL; + for (c = 0; c < SND_CARDS; c++) { + sprintf(name, "hw:%d", c); + if ((0 <= snd_hwdep_open(&hw, name, O_RDWR)) + && (0 <= check_hwinfo(hw, SND_USX2Y_LOADER_ID, usb_device_name)) + && (0 <= snd_hwdep_close(hw))){ + card = c; + break; + } + } + } + if (device_name) { + return US428Control(device_name) != 0; + } + if (card >= 0) { + sprintf(name, "hw:%d", card); + return US428Control(name) != 0; + } + + /* probe the all cards */ + for (c = 0; c < SND_CARDS; c++) { + verbose--; + sprintf(name, "hw:%d", c); + if (! US428Control(name)) + card = c; + } + if (card < 0) { + fprintf(stderr, PROGNAME ": no US-X2Y-compatible cards found\n"); + return 1; + } + return 0; +} + diff --git a/us428control/usbus428ctldefs.h b/us428control/usbus428ctldefs.h new file mode 100644 index 0000000..7ca55ab --- /dev/null +++ b/us428control/usbus428ctldefs.h @@ -0,0 +1,133 @@ +/* + * + * Copyright (c) 2003 by Karsten Wiese + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +enum E_In84{ + eFader0 = 0, + eFader1, + eFader2, + eFader3, + eFader4, + eFader5, + eFader6, + eFader7, + eFaderM, + eTransport, + eModifier = 10, + eFilterSelect, + eSelect, + eMute, + + eSwitch = 15, + eWheelGain, + eWheelFreq, + eWheelQ, + eWheelPan, + eWheel = 20 +}; + +#define T_RECORD 1 +#define T_PLAY 2 +#define T_STOP 4 +#define T_F_FWD 8 +#define T_REW 0x10 +#define T_SOLO 0x20 +#define T_REC 0x40 +#define T_NULL 0x80 + + +struct us428_ctls{ + unsigned char Fader[9]; + unsigned char Transport; + unsigned char Modifier; + unsigned char FilterSelect; + unsigned char Select; + unsigned char Mute; + unsigned char UNKNOWN; + unsigned char Switch; + unsigned char Wheel[5]; +}; + +typedef struct us428_ctls us428_ctls_t; + +typedef struct us428_setByte{ + unsigned char Offset, + Value; +}us428_setByte_t; + +enum { + eLT_Volume = 0, + eLT_Light +}; + +typedef struct usX2Y_volume { + unsigned char Channel, + LH, + LL, + RH, + RL; +#ifdef __cplusplus + public: + int Scale(){return 0x40;} + void SetTo(unsigned char _Channel, int RawValue){ + Channel = eFaderM == _Channel ? 4 : _Channel; + LH = RH = (RawValue *= Scale()) >> 8; + LL = RL = RawValue; + } +#endif +} usX2Y_volume_t; + +struct us428_lights{ + us428_setByte_t Light[7]; +#ifdef __cplusplus + public: + enum eLight{ + eL_InputMonitor = 25 + }; + bool LightIs(eLight L){ + return Light[L / 8].Value & (1 << (L % 8)); + } + void LightSet(eLight L, bool Value){ + if (Value) + Light[L / 8].Value |= (1 << (L % 8)); + else + Light[L / 8].Value &= (~1 << (L % 8)); + } + void init_us428_lights(); +#endif +}; +typedef struct us428_lights us428_lights_t; + +typedef struct { + char type; + union { + usX2Y_volume_t vol; + us428_lights_t lights; + }; +} us428_p4out_t; + +#define N_us428_ctl_BUFS 16 +#define N_us428_p4out_BUFS 16 +struct us428ctls_sharedmem{ + us428_ctls_t CtlSnapShot[N_us428_ctl_BUFS]; + int CtlSnapShotDiffersAt[N_us428_ctl_BUFS]; + int CtlSnapShotLast, CtlSnapShotRed; + us428_p4out_t p4out[N_us428_p4out_BUFS]; + int p4outLast, p4outSent; +}; +typedef struct us428ctls_sharedmem us428ctls_sharedmem_t;