summaryrefslogtreecommitdiffstats
path: root/hdlcutil/fl/xfsmmixer_main.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'hdlcutil/fl/xfsmmixer_main.cxx')
-rw-r--r--hdlcutil/fl/xfsmmixer_main.cxx462
1 files changed, 462 insertions, 0 deletions
diff --git a/hdlcutil/fl/xfsmmixer_main.cxx b/hdlcutil/fl/xfsmmixer_main.cxx
new file mode 100644
index 0000000..15c3e79
--- /dev/null
+++ b/hdlcutil/fl/xfsmmixer_main.cxx
@@ -0,0 +1,462 @@
+/*****************************************************************************/
+
+/*
+ * xfsmmixer_main.c -- kernel soundcard radio modem driver mixer utility.
+ *
+ * Copyright (C) 1996,1997,2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * 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.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ *
+ * History:
+ * 0.1 14.12.1996 Started
+ * 0.2 11.05.1997 introduced hdrvcomm.h
+ * 0.3 05.01.2000 upgraded to fltk 1.0.7
+ */
+
+/*****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <net/if.h>
+//#include <forms.h>
+#include "hdrvcomm.h"
+#include "xfsmmixer.h"
+
+/* ---------------------------------------------------------------------- */
+
+static char *progname;
+static unsigned int mixdevice;
+
+/* ---------------------------------------------------------------------- */
+
+static int do_mix_ioctl(int cmd, struct sm_mixer_data *mixdat)
+{
+ struct sm_ioctl par;
+ int i;
+
+ par.cmd = cmd;
+ par.data.mix = *mixdat;
+ i = hdrvc_sm_ioctl(cmd, &par);
+ *mixdat = par.data.mix;
+ return i;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned char get_mixer_reg(unsigned char addr)
+{
+ int i;
+ struct sm_mixer_data mixdat;
+
+ mixdat.reg = addr;
+ if ((i = do_mix_ioctl(SMCTL_GETMIXER, &mixdat)) < 0) {
+ perror("do_mix_ioctl: SMCTL_GETMIXER");
+ exit(1);
+ }
+ if (!i)
+ fprintf(stderr, "warning: mixer device %u register %u not "
+ "accessible for reading!\n", mixdat.mixer_type,
+ addr);
+ if (mixdat.mixer_type != mixdevice) {
+ fprintf(stderr, "error: mixer type changed !?\n");
+ exit(2);
+ }
+ return mixdat.data;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void set_mixer_reg(unsigned char addr, unsigned char data)
+{
+ struct sm_mixer_data mixdat;
+
+ mixdat.reg = addr;
+ mixdat.data = data;
+ mixdat.mixer_type = mixdevice;
+ if (do_mix_ioctl(SMCTL_SETMIXER, &mixdat) < 0) {
+ perror("do_mix_ioctl: SMCTL_SETMIXER");
+ exit(1);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void update_ad1848(Fl_Widget *widget, void *udata)
+{
+ unsigned char mdata;
+ float mval;
+
+ mdata = 0;
+ if (ad1848_srcl_line->value())
+ mdata = 0x00;
+ else if (ad1848_srcl_aux1->value())
+ mdata = 0x40;
+ else if (ad1848_srcl_mic->value())
+ mdata = 0x80;
+ else if (ad1848_srcl_dac->value())
+ mdata = 0xc0;
+ mval = ad1848_inl->value();
+ if (mdata == 0x80 && mval >= 20) {
+ mval -= 20;
+ mdata |= 0x20;
+ }
+ mval *= 0.666666;
+ if (mval > 15)
+ mval = 15;
+ mdata |= (int)mval;
+ set_mixer_reg(0x00, mdata);
+ mdata = 0;
+ if (ad1848_srcr_line->value())
+ mdata = 0x00;
+ else if (ad1848_srcr_aux1->value())
+ mdata = 0x40;
+ else if (ad1848_srcr_mic->value())
+ mdata = 0x80;
+ else if (ad1848_srcr_dac->value())
+ mdata = 0xc0;
+ mval = ad1848_inr->value();
+ if (mdata == 0x80 && mval >= 20) {
+ mval -= 20;
+ mdata |= 0x20;
+ }
+ mval *= 0.666666;
+ if (mval > 15)
+ mval = 15;
+ mdata |= (int)mval;
+ set_mixer_reg(0x01, mdata);
+ set_mixer_reg(0x02, 0x80);
+ set_mixer_reg(0x03, 0x80);
+ set_mixer_reg(0x04, 0x80);
+ set_mixer_reg(0x05, 0x80);
+ mval = ad1848_outl->value();
+ if (mval < -95)
+ set_mixer_reg(0x06, 0x80);
+ else
+ set_mixer_reg(0x06, (unsigned char)(mval * (-0.66666666)));
+ mval = ad1848_outr->value();
+ if (mval < -95)
+ set_mixer_reg(0x07, 0x80);
+ else
+ set_mixer_reg(0x07, (unsigned char)(mval * (-0.66666666)));
+ set_mixer_reg(0x0d, 0x00);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void update_ct1335(Fl_Widget *widget, void *udata)
+{
+ float mval;
+
+ mval = ct1335_out->value() * (7.0 / 46.0);
+ set_mixer_reg(0x02, ((((int)(mval)) + 7) << 1));
+ set_mixer_reg(0x06, 0x00);
+ set_mixer_reg(0x08, 0x00);
+ set_mixer_reg(0x0a, 0x06);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void update_ct1345(Fl_Widget *widget, void *udata)
+{
+ unsigned char mdata;
+ double mval;
+
+ set_mixer_reg(0x04, 0xee);
+ set_mixer_reg(0x0a, 0x00);
+ mdata = 0x20;
+ if (ct1345_src_mic->value())
+ mdata = 0x20;
+ else if (ct1345_src_cd->value())
+ mdata = 0x22;
+ else if (ct1345_src_line->value())
+ mdata = 0x26;
+ set_mixer_reg(0x0c, mdata);
+ set_mixer_reg(0x0e, 0x20);
+ mval = ct1345_outl->value() * (7.0 / 46.0);
+ mdata = (((int)(mval))+7) << 5;
+ mval = ct1345_outr->value() * (7.0 / 46.0);
+ mdata |= (((int)(mval))+7) << 1;
+ set_mixer_reg(0x22, mdata);
+ set_mixer_reg(0x26, 0x00);
+ set_mixer_reg(0x28, 0x00);
+ set_mixer_reg(0x2e, 0x00);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void update_ct1745(Fl_Widget *widget, void *udata)
+{
+ unsigned char mdata;
+ float mval;
+
+ set_mixer_reg(0x3c, 0); /* output src: only voice and pcspk */
+ mval = ct1745_treble->value();
+ set_mixer_reg(0x44, ((int)mval)<<4); /* treble.l */
+ set_mixer_reg(0x45, ((int)mval)<<4); /* treble.r */
+ mval = ct1745_bass->value();
+ set_mixer_reg(0x46, ((int)mval)<<4); /* bass.l */
+ set_mixer_reg(0x47, ((int)mval)<<4); /* bass.r */
+ set_mixer_reg(0x3b, 0); /* PC speaker vol -18dB */
+ set_mixer_reg(0x43, 1); /* mic: agc off, fixed 20dB gain */
+ mval = ct1745_outl->value();
+ mdata = 0;
+ while (mval > 0) {
+ mval -= 6;
+ mdata += 0x40;
+ }
+ set_mixer_reg(0x41, mdata); /* output gain */
+ set_mixer_reg(0x30, 0xf8); /* master vol */
+ set_mixer_reg(0x32, ((int)(mval * 0.5) + 31) << 3); /* voice vol */
+ mval = ct1745_outr->value();
+ mdata = 0;
+ while (mval > 0) {
+ mval -= 6;
+ mdata += 0x40;
+ }
+ set_mixer_reg(0x42, mdata); /* output gain */
+ set_mixer_reg(0x31, 0xf8); /* master vol */
+ set_mixer_reg(0x33, ((int)(mval * 0.5) + 31) << 3); /* voice vol */
+ mval = ct1745_inl->value();
+ mdata = 0;
+ while (mval > 0) {
+ mval -= 6;
+ mdata += 0x40;
+ }
+ set_mixer_reg(0x3f, mdata); /* input gain */
+ mdata = ((int)(mval * 0.5) + 31) << 3;
+ set_mixer_reg(0x34, mdata); /* midi vol */
+ set_mixer_reg(0x36, mdata); /* cd vol */
+ set_mixer_reg(0x38, mdata); /* line vol */
+ set_mixer_reg(0x3a, mdata); /* mic vol */
+ mval = ct1745_inr->value();
+ mdata = 0;
+ while (mval > 0) {
+ mval -= 6;
+ mdata += 0x40;
+ }
+ set_mixer_reg(0x40, mdata); /* input gain */
+ mdata = ((int)(mval * 0.5) + 31) << 3;
+ set_mixer_reg(0x35, mdata); /* midi vol */
+ set_mixer_reg(0x37, mdata); /* cd vol */
+ set_mixer_reg(0x39, mdata); /* line vol */
+ mdata = 0;
+ if (ct1745_srcl_mic->value())
+ mdata |= 0x01;
+ if (ct1745_srcl_cdl->value())
+ mdata |= 0x04;
+ if (ct1745_srcl_cdr->value())
+ mdata |= 0x02;
+ if (ct1745_srcl_linel->value())
+ mdata |= 0x10;
+ if (ct1745_srcl_liner->value())
+ mdata |= 0x08;
+ if (ct1745_srcl_midil->value())
+ mdata |= 0x40;
+ if (ct1745_srcl_midir->value())
+ mdata |= 0x20;
+ set_mixer_reg(0x3d, mdata); /* input sources left */
+ mdata = 0;
+ if (ct1745_srcr_mic->value())
+ mdata |= 0x01;
+ if (ct1745_srcr_cdl->value())
+ mdata |= 0x04;
+ if (ct1745_srcr_cdr->value())
+ mdata |= 0x02;
+ if (ct1745_srcr_linel->value())
+ mdata |= 0x10;
+ if (ct1745_srcr_liner->value())
+ mdata |= 0x08;
+ if (ct1745_srcr_midil->value())
+ mdata |= 0x40;
+ if (ct1745_srcr_midir->value())
+ mdata |= 0x20;
+ set_mixer_reg(0x3e, mdata); /* input sources right*/
+}
+
+/* ---------------------------------------------------------------------- */
+
+void cb_quit(Fl_Button *, long)
+{
+ exit (0);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static const char *usage_str =
+"[-i smif]\n"
+" -i: specify the name of the soundmodem kernel driver interface\n\n";
+
+/* ---------------------------------------------------------------------- */
+
+int main(int argc, char *argv[])
+{
+ int c, i;
+ struct sm_mixer_data mixdat;
+ unsigned char mdata;
+
+ progname = *argv;
+ printf("%s: Version 0.3; (C) 1996,1997,2000 by Thomas Sailer HB9JNX/AE4WA\n", progname);
+ hdrvc_args(&argc, argv, "sm0");
+ for (i = 1; i < argc; ) {
+ c = i;
+ Fl::arg(argc, argv, c);
+ if (c <= 0) {
+ i++;
+ continue;
+ }
+ memmove(&argv[i], &argv[i+c], (argc-i) * sizeof(char *));
+ argc -= c;
+ }
+#if 0
+ while ((ret = getopt(argc, argv, "")) != -1) {
+ switch (ret) {
+ default:
+ printf("usage: %s %s", progname, usage_str);
+ exit(-1);
+ }
+ }
+#endif
+ hdrvc_init();
+ /*
+ * set mixer
+ */
+ mixdat.reg = 0;
+ if (do_mix_ioctl(SMCTL_GETMIXER, &mixdat) < 0) {
+ perror("do_mix_ioctl: SMCTL_GETMIXER");
+ mixdevice = SM_MIXER_INVALID;
+ } else
+ mixdevice = mixdat.mixer_type;
+ switch (mixdevice) {
+ case SM_MIXER_INVALID:
+ printf("invalid mixer device\n");
+ exit(1);
+
+ case SM_MIXER_AD1848:
+ case SM_MIXER_CRYSTAL:
+ printf("Mixer device: %s\n", mixdevice == SM_MIXER_CRYSTAL ?
+ "CS423x" : "AD1848");
+ create_form_ad1848();
+ mdata = get_mixer_reg(0);
+ ad1848_inl->step(1.5);
+ ad1848_inl->bounds(42.5, 0);
+ ad1848_inl->value((((mdata & 0xe0) == 0xa0) ? 20 : 0) + (mdata & 0xf) * 1.5);
+ ad1848_srcl_line->value((mdata & 0xc0) == 0x00);
+ ad1848_srcl_aux1->value((mdata & 0xc0) == 0x40);
+ ad1848_srcl_mic->value((mdata & 0xc0) == 0x80);
+ ad1848_srcl_dac->value((mdata & 0xc0) == 0xc0);
+ mdata = get_mixer_reg(1);
+ ad1848_inr->step(1.5);
+ ad1848_inr->bounds(42.5, 0);
+ ad1848_inr->value((((mdata & 0xe0) == 0xa0) ? 20 : 0) + (mdata & 0xf) * 1.5);
+ ad1848_srcr_line->value((mdata & 0xc0) == 0x00);
+ ad1848_srcr_aux1->value((mdata & 0xc0) == 0x40);
+ ad1848_srcr_mic->value((mdata & 0xc0) == 0x80);
+ ad1848_srcr_dac->value((mdata & 0xc0) == 0xc0);
+ mdata = get_mixer_reg(6);
+ ad1848_outl->step(1.5);
+ ad1848_outl->bounds(0, -100);
+ ad1848_outl->value((mdata & 0x80) ? -100 : (mdata & 0x3f) * -1.5);
+ mdata = get_mixer_reg(7);
+ ad1848_outr->step(1.5);
+ ad1848_outr->bounds(0, -100);
+ ad1848_outr->value((mdata & 0x80) ? -100 : (mdata & 0x3f) * -1.5);
+ mixer_ad1848->show();
+ break;
+
+ case SM_MIXER_CT1335:
+ printf("Mixer device: CT1335\n");
+ create_form_ct1335();
+ mdata = get_mixer_reg(0x2);
+ ct1335_out->step(46.0/7.0);
+ ct1335_out->bounds(0, -46);
+ ct1335_out->value((((int)((mdata >> 1) & 7)) - 7) * (46.0/7.0));
+ mixer_ct1335->show();
+ break;
+
+ case SM_MIXER_CT1345:
+ printf("Mixer device: CT1345\n");
+ create_form_ct1345();
+ mdata = get_mixer_reg(0x22);
+ ct1345_outl->step(46.0/7.0);
+ ct1345_outl->bounds(0, -46);
+ ct1345_outl->value((((int)((mdata >> 5) & 7)) - 7) * (46.0/7.0));
+ ct1345_outr->step(46.0/7.0);
+ ct1345_outr->bounds(0, -46);
+ ct1345_outr->value((((int)((mdata >> 1) & 7)) - 7) * (46.0/7.0));
+ mdata = get_mixer_reg(0xc);
+ ct1345_src_mic->value((mdata & 6) == 0 || (mdata & 6) == 4);
+ ct1345_src_cd->value((mdata & 6) == 2);
+ ct1345_src_line->value((mdata & 6) == 6);
+ mixer_ct1345->show();
+ break;
+
+ case SM_MIXER_CT1745:
+ printf("Mixer device: CT1745\n");
+ create_form_ct1745();
+ ct1745_outl->step(2);
+ ct1745_outl->bounds(0, -62);
+ ct1745_outl->value(((int)((get_mixer_reg(0x32) >> 3) & 0x1f) - 31) * 2 +
+ ((get_mixer_reg(0x41) >> 6) & 0x3) * 6);
+ ct1745_outr->step(2);
+ ct1745_outr->bounds(0, -62);
+ ct1745_outr->value(((int)((get_mixer_reg(0x33) >> 3) & 0x1f) - 31) * 2 +
+ ((get_mixer_reg(0x42) >> 6) & 0x3) * 6);
+ ct1745_inl->step(2);
+ ct1745_inl->bounds(0, -62);
+ ct1745_inl->value(((int)((get_mixer_reg(0x38) >> 3) & 0x1f) - 31) * 2 +
+ ((get_mixer_reg(0x3f) >> 6) & 0x3) * 6);
+ ct1745_inr->step(2);
+ ct1745_inr->bounds(0, -62);
+ ct1745_inr->value(((int)((get_mixer_reg(0x39) >> 3) & 0x1f) - 31) * 2 +
+ ((get_mixer_reg(0x40) >> 6) & 0x3) * 6);
+ mdata = get_mixer_reg(0x3d);
+ ct1745_srcl_mic->value(!!(mdata & 1));
+ ct1745_srcl_cdl->value(!!(mdata & 4));
+ ct1745_srcl_cdr->value(!!(mdata & 2));
+ ct1745_srcl_linel->value(!!(mdata & 0x10));
+ ct1745_srcl_liner->value(!!(mdata & 8));
+ ct1745_srcl_midil->value(!!(mdata & 0x40));
+ ct1745_srcl_midir->value(!!(mdata & 0x20));
+ mdata = get_mixer_reg(0x3e);
+ ct1745_srcr_mic->value(!!(mdata & 1));
+ ct1745_srcr_cdl->value(!!(mdata & 4));
+ ct1745_srcr_cdr->value(!!(mdata & 2));
+ ct1745_srcr_linel->value(!!(mdata & 0x10));
+ ct1745_srcr_liner->value(!!(mdata & 8));
+ ct1745_srcr_midil->value(!!(mdata & 0x40));
+ ct1745_srcr_midir->value(!!(mdata & 0x20));
+ ct1745_treble->step(1);
+ ct1745_treble->bounds(7, -8);
+ ct1745_treble->value((get_mixer_reg(0x44) >> 4) & 0xf);
+ ct1745_bass->step(1);
+ ct1745_bass->bounds(7, -8);
+ ct1745_bass->value((get_mixer_reg(0x46) >> 4) & 0xf);
+ mixer_ct1745->show();
+ break;
+
+ default:
+ printf("unknown mixer device %d\n", mixdevice);
+ exit(1);
+ }
+ Fl::run();
+ exit(0);
+}