diff -dupr us428control-0.4.4-0/configure.in us428control-0.4.5-5/configure.in --- us428control-0.4.4-0/configure.in 2006-12-07 14:27:24.000000000 +0000 +++ us428control-0.4.5-5/configure.in 2007-02-09 18:01:59.000000000 +0000 @@ -1,5 +1,5 @@ AC_INIT(us428control.cc) -AM_INIT_AUTOMAKE(us428control, 0.4.4) +AM_INIT_AUTOMAKE(us428control, 0.4.5) AC_PROG_CXX AC_PROG_INSTALL AC_HEADER_STDC diff -dupr us428control-0.4.4-0/Cus428Midi.cc us428control-0.4.5-5/Cus428Midi.cc --- us428control-0.4.4-0/Cus428Midi.cc 2006-12-07 14:27:24.000000000 +0000 +++ us428control-0.4.5-5/Cus428Midi.cc 2007-02-13 18:39:14.000000000 +0000 @@ -2,6 +2,7 @@ /* * * Copyright (c) 2003 by Karsten Wiese + * Copyright (c) 2004-2007 by Rui Nuno Capela * * 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 @@ -140,6 +141,11 @@ void Cus428Midi::ProcessMidiEvents() fprintf(stderr, "LOCATE.\n"); OneState->LocateWheel(&data[7]); break; + case MMC_CMD_MASKED_WRITE: + if (verbose > 1) + fprintf(stderr, "MASKED WRITE.\n"); + OneState->MaskedWrite(&data[6]); + break; case MMC_CMD_MMC_RESET: if (verbose > 1) fprintf(stderr, "MMC RESET.\n"); diff -dupr us428control-0.4.4-0/Cus428Midi.h us428control-0.4.5-5/Cus428Midi.h --- us428control-0.4.4-0/Cus428Midi.h 2006-12-07 14:27:24.000000000 +0000 +++ us428control-0.4.5-5/Cus428Midi.h 2007-02-14 18:20:57.000000000 +0000 @@ -2,6 +2,7 @@ /* * * Copyright (c) 2003 by Karsten Wiese + * Copyright (c) 2004-2007 by Rui Nuno Capela * * 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 @@ -61,6 +62,11 @@ #define MMC_CMD_WAIT 0x7c #define MMC_CMD_RESUME 0x7f +// Available MMC Masked Write sub-commands (information fields). +#define MMC_CIF_TRACK_RECORD 0x4f +#define MMC_CIF_TRACK_MUTE 0x62 +#define MMC_CIF_TRACK_SOLO 0x66 // Custom-implementation ;) + class Cus428Midi { public: diff -dupr us428control-0.4.4-0/Cus428State.cc us428control-0.4.5-5/Cus428State.cc --- us428control-0.4.4-0/Cus428State.cc 2006-12-07 14:27:24.000000000 +0000 +++ us428control-0.4.5-5/Cus428State.cc 2007-02-14 18:18:53.000000000 +0000 @@ -3,6 +3,7 @@ * Controller for Tascam US-X2Y * * Copyright (c) 2003 by Karsten Wiese + * Copyright (c) 2004-2007 by Rui Nuno Capela * * 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 @@ -84,9 +85,9 @@ void Cus428State::SliderChangedTo(int S, V.SetTo(S, New); if (S == eFaderM || !LightIs(eL_Mute0 + S)) SendVolume(V); - } - else + } else { UserSliderChangedTo(S, New); + } } void Cus428State::UserKnobChangedTo(eKnobs K, bool V) @@ -132,12 +133,12 @@ void Cus428State::UserKnobChangedTo(eKno break; case eK_SET: if (verbose > 1) - printf("Knob SET now %i", V); + printf("Knob SET now %i\n", V); bSetLocate = V; break; case eK_LOCATE_L: if (verbose > 1) - printf("Knob LOCATE_L now %i", V); + printf("Knob LOCATE_L now %i\n", V); if (V) { if (bSetLocate) aWheel_L = aWheel; @@ -149,7 +150,7 @@ void Cus428State::UserKnobChangedTo(eKno break; case eK_LOCATE_R: if (verbose > 1) - printf("Knob LOCATE_R now %i", V); + printf("Knob LOCATE_R now %i\n", V); if (V) { if (bSetLocate) aWheel_R = aWheel; @@ -159,6 +160,118 @@ void Cus428State::UserKnobChangedTo(eKno } } break; + case eK_REC: + if (verbose > 1) + printf("Knob REC now %i\n", V); + bSetRecord = V; + break; + case eK_SOLO: + if (verbose > 1) + printf("Knob SOLO now %i", V); + if (V) { + bool bSolo = ! LightIs(eL_Solo); + if (StateInputMonitor()) { + if (bSolo) { + MuteInputMonitor = Light[2].Value; + Light[2].Value = SoloInputMonitor; + } else { + SoloInputMonitor = Light[2].Value; + Light[2].Value = MuteInputMonitor; + } + } else { + if (bSolo) { + Mute[aBank] = Light[2].Value; + Light[2].Value = Solo[aBank]; + } else { + Solo[aBank] = Light[2].Value; + Light[2].Value = Mute[aBank]; + } + } + LightSet(eL_Solo, bSolo); + LightSend(); + } + if (verbose > 1) + printf(" Light is %i\n", LightIs(eL_Solo)); + break; + case eK_NULL: + if (verbose > 1) + printf("Knob NULL now %i", V); + if (V) { + bool bNull = ! LightIs(eL_Null); + LightSet(eL_Null, bNull); + LightSend(); + } + if (verbose > 1) + printf(" Light is %i\n", LightIs(eL_Null)); + break; + case eK_BANK_L: + if (verbose > 1) + printf("Knob BANK_L now %i", V); + if (V) { + if (aBank > 0) { + bool bInputMonitor = StateInputMonitor(); + bool bSolo = LightIs(eL_Solo); + if (!bInputMonitor) { + Select[aBank] = Light[0].Value; + Rec[aBank] = Light[1].Value; + if (bSolo) { + Solo[aBank] = Light[2].Value; + } else { + Mute[aBank] = Light[2].Value; + } + } + aBank--; + if (!bInputMonitor) { + Light[0].Value = Select[aBank]; + Light[1].Value = Rec[aBank]; + if (bSolo) { + Light[2].Value = Solo[aBank]; + } else { + Light[2].Value = Mute[aBank]; + } + } + } + LightSet(eL_BankL, (aBank == 0)); + LightSet(eL_BankR, (aBank == cBanks - 1)); + LightSend(); + } + if (verbose > 1) + printf(" Light is %i\n", LightIs(eL_BankL)); + break; + case eK_BANK_R: + if (verbose > 1) + printf("Knob BANK_R now %i", V); + if (V) { + if (aBank < 3) { + bool bInputMonitor = StateInputMonitor(); + bool bSolo = LightIs(eL_Solo); + if (!bInputMonitor) { + Select[aBank] = Light[0].Value; + Rec[aBank] = Light[1].Value; + if (bSolo) { + Solo[aBank] = Light[2].Value; + } else { + Mute[aBank] = Light[2].Value; + } + } + aBank++; + if (!bInputMonitor) { + Light[0].Value = Select[aBank]; + Light[1].Value = Rec[aBank]; + if (bSolo) { + Light[2].Value = Solo[aBank]; + } else { + Light[2].Value = Mute[aBank]; + } + } + } + LightSet(eL_BankL, (aBank == 0)); + LightSet(eL_BankR, (aBank == cBanks - 1)); + LightSend(); + } + if (verbose > 1) + printf(" Light is %i\n", LightIs(eL_BankR)); + break; default: if (verbose > 1) printf("Knob %i now %i\n", K, V); @@ -169,12 +282,21 @@ void Cus428State::UserKnobChangedTo(eKno void Cus428State::KnobChangedTo(eKnobs K, bool V) { - switch (K & ~(StateInputMonitor() ? 3 : -1)) { +// switch (K & ~(StateInputMonitor() ? 3 : -1)) { + switch (K & ~3) { case eK_Select0: if (V) { int S = eL_Select0 + (K & 7); Light[eL_Select0 / 8].Value = 0; LightSet(S, !LightIs(S)); + if (bSetRecord) { + int R = eL_Rec0 + (K & 7); + LightSet(R, !LightIs(R)); + if (!StateInputMonitor()) { + SendMaskedWrite(MMC_CIF_TRACK_RECORD, + Y * aBank + (K & 7), LightIs(R)); + } + } LightSend(); } break; @@ -184,10 +306,27 @@ void Cus428State::KnobChangedTo(eKnobs K LightSet(M, !LightIs(M)); LightSend(); if (StateInputMonitor()) { - usX2Y_volume V = Volume[M - eL_Mute0]; - if (LightIs(M)) - V.LH = V.LL = V.RL = V.RH = 0; - SendVolume(V); + if (LightIs(eL_Solo)) { + for (int i = 0; i < 8; ++i) { + usX2Y_volume V = Volume[i]; + if (!LightIs(eL_Mute0 + i) || (MuteInputMonitor & (1 << i))) + V.LH = V.LL = V.RL = V.RH = 0; + SendVolume(V); + } + } else { + usX2Y_volume V = Volume[M - eL_Mute0]; + if (LightIs(M)) + V.LH = V.LL = V.RL = V.RH = 0; + SendVolume(V); + } + } else { + if (LightIs(eL_Solo)) { + SendMaskedWrite(MMC_CIF_TRACK_SOLO, + Y * aBank + (K & 7), LightIs(M)); + } else { + SendMaskedWrite(MMC_CIF_TRACK_MUTE, + Y * aBank + (K & 7), LightIs(M)); + } } } break; @@ -196,16 +335,33 @@ void Cus428State::KnobChangedTo(eKnobs K if (verbose > 1) printf("Knob InputMonitor now %i", V); if (V) { - if (StateInputMonitor()) { - SelectInputMonitor = Light[0].Value; - MuteInputMonitor = Light[2].Value; + bool bInputMonitor = ! StateInputMonitor(); + if (bInputMonitor) { + Select[aBank] = Light[0].Value; + Rec[aBank] = Light[1].Value; + Light[0].Value = SelectInputMonitor; + Light[1].Value = RecInputMonitor; + if (LightIs(eL_Solo)) { + Solo[aBank] = Light[2].Value; + Light[2].Value = SoloInputMonitor; + } else { + Mute[aBank] = Light[2].Value; + Light[2].Value = MuteInputMonitor; + } } else { - Select = Light[0].Value; - Mute = Light[2].Value; + SelectInputMonitor = Light[0].Value; + RecInputMonitor = Light[1].Value; + Light[0].Value = Select[aBank]; + Light[1].Value = Rec[aBank]; + if (LightIs(eL_Solo)) { + SoloInputMonitor = Light[2].Value; + Light[2].Value = Solo[aBank]; + } else { + MuteInputMonitor = Light[2].Value; + Light[2].Value = Mute[aBank]; + } } - LightSet(eL_InputMonitor, ! StateInputMonitor()); - Light[0].Value = StateInputMonitor() ? SelectInputMonitor : Select; - Light[2].Value = StateInputMonitor() ? MuteInputMonitor : Mute; + LightSet(eL_InputMonitor, bInputMonitor); LightSend(); } if (verbose > 1) @@ -232,8 +388,8 @@ void Cus428State::UserWheelChangedTo(E_I Param = 0x4A; break; case eWheel: - Param = 0x60; - // Update the absolute wheel position. + Param = 0x60; + // Update the absolute wheel position. WheelDelta((int) ((unsigned char *) us428_ctls)[W]); break; } @@ -242,21 +398,18 @@ void Cus428State::UserWheelChangedTo(E_I void Cus428State::WheelChangedTo(E_In84 W, char Diff) { - if (W == eWheelPan && StateInputMonitor() && Light[0].Value) - { - int index = 0; - - while( index < 4 && (1 << index) != Light[0].Value) - index++; - - if (index >= 4) - return; - - Volume[index].PanTo(Diff, us428_ctls->Knob(eK_SET)); - if (!LightIs(eL_Mute0 + index)) - SendVolume(Volume[index]); + if (W == eWheelPan && StateInputMonitor() && Light[0].Value) { + int index = 0; + while( index < 4 && (1 << index) != Light[0].Value) + index++; + if (index >= 4) return; - } + Volume[index].PanTo(Diff, us428_ctls->Knob(eK_SET)); + if (!LightIs(eL_Mute0 + index)) + SendVolume(Volume[index]); + return; + } + UserWheelChangedTo(W, Diff); } @@ -265,9 +418,9 @@ void Cus428State::WheelChangedTo(E_In84 void Cus428State::LocateWheel ( unsigned char *tc ) { aWheel = (60 * 60 * 30) * (int) tc[0] // hh - hours [0..23] - + ( 60 * 30) * (int) tc[1] // mm - minutes [0..59] - + ( 30) * (int) tc[2] // ss - seconds [0..59] - + (int) tc[3]; // ff - frames [0..29] + + ( 60 * 30) * (int) tc[1] // mm - minutes [0..59] + + ( 30) * (int) tc[2] // ss - seconds [0..59] + + (int) tc[3]; // ff - frames [0..29] } @@ -426,6 +579,7 @@ void Cus428State::TransportSet ( unsigne TransportSend(); } + // Update transport status lights. void Cus428State::TransportSend() { @@ -447,6 +601,7 @@ void Cus428State::TransportSend() LightSend(); } + // Reset MMC state. void Cus428State::MmcReset() { @@ -454,13 +609,101 @@ void Cus428State::MmcReset() aWheel = aWheel_L = aWheel_R = 0; aWheelSpeed = 0; bSetLocate = false; + bSetRecord = false; uTransport = 0; TransportSend(); LocateSend(); } -Cus428StateMixxx::Cus428StateMixxx(struct us428ctls_sharedmem* Pus428ctls_sharedmem):Cus428State(Pus428ctls_sharedmem) + +// Process MMC maked-write sub-command. +void Cus428State::MaskedWrite ( unsigned char *data ) +{ + // data[0] - sub-command / information field. + // data[1] - target track bitmap byte address. + // data[2] - bitmap changed mask. + // data[3] - bitmap changed value. + + int track = (data[1] > 0 ? (data[1] * 7) : 0) - 5; + for (int i = 0; i < 7; ++i) { + int mask = (1 << i); + if (data[2] & mask) { + // Only touch tracks that have the "mask" bit set. + int enable = (data[3] & mask); + int bank = (track / Y); + int N = (track % Y); + switch (data[0]) { + case MMC_CIF_TRACK_RECORD: + if (verbose > 1) + fprintf(stderr, "TRACK RECORD(%d, %d).\n", track, enable); + if (!StateInputMonitor() && bank >= 0 && bank < cBanks) { + if (bank == aBank) { + LightSet(eL_Rec0 + N, enable); + LightSend(); + } else if (enable) { + Rec[bank] |= (1 << N); + } else { + Rec[bank] &= ~(1 << N); + } + } + break; + case MMC_CIF_TRACK_MUTE: + if (verbose > 1) + fprintf(stderr, "TRACK MUTE(%d, %d).\n", track, enable); + if (!StateInputMonitor() && bank >= 0 && bank < cBanks) { + if (bank == aBank && !LightIs(eL_Solo)) { + LightSet(eL_Mute0 + N, enable); + LightSend(); + } else if (enable) { + Mute[bank] |= (1 << N); + } else { + Mute[bank] &= ~(1 << N); + } + } + break; + case MMC_CIF_TRACK_SOLO: + if (verbose > 1) + fprintf(stderr, "TRACK SOLO(%d, %d).\n", track, enable); + if (!StateInputMonitor() && bank >= 0 && bank < cBanks) { + if (bank == aBank && LightIs(eL_Solo)) { + LightSet(eL_Mute0 + N, enable); + LightSend(); + } else if (enable) { + Solo[bank] |= (1 << N); + } else { + Solo[bank] &= ~(1 << N); + } + } + break; + default: + break; + } + } + track++; + } +} + + +// Send own MMC masked-write subcommand. +void Cus428State::SendMaskedWrite ( unsigned char scmd, int track, bool V ) +{ + unsigned char data[4]; + int mask = (1 << (track < 2 ? track + 5 : (track - 2) % 7)); + + data[0] = scmd; + data[1] = (unsigned char) (track < 2 ? 0 : 1 + (track - 2) / 7); + data[2] = (unsigned char) mask; + data[3] = (unsigned char) (V ? mask : 0); + + Midi.SendMmcCommand(MMC_CMD_MASKED_WRITE, &data[0], sizeof(data)); +} + + + +Cus428StateMixxx::Cus428StateMixxx( + struct us428ctls_sharedmem* Pus428ctls_sharedmem, int y) + : Cus428State(Pus428ctls_sharedmem, y) { focus = 0; eq = 0; @@ -476,26 +719,26 @@ void Cus428StateMixxx::UserKnobChangedTo switch (K) { case eK_BANK_L: if (verbose > 1) - printf("Knob BANK_L now %i", V); + printf("Knob BANK_L now %i\n", V); if (V) LightSet(eL_BankL, !LightIs(eL_BankL)); LightSend(); Midi.SendMidiNote(0, 51, V ? 127 : 0); break; case eK_BANK_R: if (verbose > 1) - printf("Knob BANK_R now %i", V); + printf("Knob BANK_R now %i\n", V); if (V) LightSet(eL_BankR, !LightIs(eL_BankR)); LightSend(); Midi.SendMidiNote(1, 51, V ? 127 : 0); break; case eK_REW: if (verbose > 1) - printf("Knob REW now %i", V); + printf("Knob REW now %i\n", V); Midi.SendMidiNote(focus, 60, V ? 127 : 0); break; case eK_FFWD: if (verbose > 1) - printf("Knob FFWD now %i", V); + printf("Knob FFWD now %i\n", V); Midi.SendMidiNote(focus, 61, V ? 127 : 0); break; case eK_STOP: @@ -505,17 +748,17 @@ void Cus428StateMixxx::UserKnobChangedTo break; case eK_PLAY: if (verbose > 1) - printf("Knob PLAY now %i", V); + printf("Knob PLAY now %i\n", V); Midi.SendMidiNote(focus, 63, V ? 127 : 0); break; case eK_RECORD: if (verbose > 1) - printf("Knob RECORD now %i", V); + printf("Knob RECORD now %i\n", V); Midi.SendMidiNote(focus, 64, V ? 127 : 0); break; case eK_LOW: if (verbose > 1) - printf("Knob LOW now %i", V); + printf("Knob LOW now %i\n", V); if (V) { eq = 0; @@ -528,7 +771,7 @@ void Cus428StateMixxx::UserKnobChangedTo break; case eK_LOWMID: if (verbose > 1) - printf("Knob LOWMID now %i", V); + printf("Knob LOWMID now %i\n", V); if (V) { eq = 1; @@ -541,7 +784,7 @@ void Cus428StateMixxx::UserKnobChangedTo break; case eK_HIMID: if (verbose > 1) - printf("Knob HIMID now %i", V); + printf("Knob HIMID now %i\n", V); if (V) { eq = 2; @@ -554,7 +797,7 @@ void Cus428StateMixxx::UserKnobChangedTo break; case eK_HIGH: if (verbose > 1) - printf("Knob HIGH now %i", V); + printf("Knob HIGH now %i\n", V); if (V) { eq = 3; @@ -567,19 +810,19 @@ void Cus428StateMixxx::UserKnobChangedTo break; case eK_SET: if (verbose > 1) - printf("Knob SET now %i", V); + printf("Knob SET now %i\n", V); Midi.SendMidiNote(focus, 65, V ? 127 : 0); break; case eK_LOCATE_L: if (verbose > 1) - printf("Knob LOCATE_L now %i", V); + printf("Knob LOCATE_L now %i\n", V); if (V) { focus = 0; } break; case eK_LOCATE_R: if (verbose > 1) - printf("Knob LOCATE_R now %i", V); + printf("Knob LOCATE_R now %i\n", V); if (V) { focus = 1; } diff -dupr us428control-0.4.4-0/Cus428State.h us428control-0.4.5-5/Cus428State.h --- us428control-0.4.4-0/Cus428State.h 2006-12-07 14:27:24.000000000 +0000 +++ us428control-0.4.5-5/Cus428State.h 2007-02-14 18:15:55.000000000 +0000 @@ -3,6 +3,7 @@ * Controller for Tascam US-X2Y * * Copyright (c) 2003 by Karsten Wiese + * Copyright (c) 2004-2007 by Rui Nuno Capela * * 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 @@ -24,29 +25,50 @@ #include "Cus428_ctls.h" -class Cus428State: public us428_lights{ +class Cus428State: public us428_lights +{ public: - Cus428State(struct us428ctls_sharedmem* Pus428ctls_sharedmem) - :us428ctls_sharedmem(Pus428ctls_sharedmem) + + // Constructor. + Cus428State(struct us428ctls_sharedmem* Pus428ctls_sharedmem, int y = 8) + :us428ctls_sharedmem(Pus428ctls_sharedmem),Y(y) + ,us428_ctls(0) ,MuteInputMonitor(0) - ,Mute(0) + ,SoloInputMonitor(0) + ,RecInputMonitor(0) ,SelectInputMonitor(0) - ,Select(0) - ,us428_ctls(0) + ,aBank(0) + ,cBanks(32 / y) ,W0(0) ,aWheel(0) ,aWheel_L(0) ,aWheel_R(0) ,bSetLocate(false) + ,bSetRecord(false) ,uTransport(0) ,aWheelSpeed(0) { + Mute = new unsigned char [cBanks]; + Solo = new unsigned char [cBanks]; + Rec = new unsigned char [cBanks]; + Select = new unsigned char [cBanks]; + for (int i = 0; i < cBanks; ++i) + Mute[i] = Solo[i] = Rec[i] = Select[i] = 0; init_us428_lights(); for (int v = 0; v < 5; ++v) { Volume[v].init(v); } } - enum eKnobs{ + + // Destructor. + virtual ~Cus428State() { + delete Select; + delete Rec; + delete Solo; + delete Mute; + } + + enum eKnobs { eK_RECORD = 72, eK_PLAY, eK_STOP, @@ -84,6 +106,7 @@ public: eK_F2, eK_F3, }; + void InitDevice(void); void KnobChangedTo(eKnobs K, bool V); @@ -108,9 +131,13 @@ public: void TransportToggle(unsigned char T); void TransportSet(unsigned char T, bool V); void TransportSend(); + // Process masked-write sub-command. + void MaskedWrite(unsigned char *data); // Reset internal MMC state. void MmcReset(); + protected: + void SendVolume(usX2Y_volume &V); struct us428ctls_sharedmem* us428ctls_sharedmem; bool StateInputMonitor() { @@ -124,13 +151,19 @@ protected: void WheelShuttle(int dW); // Get the curent wheel timecode. void LocateTimecode(unsigned char *tc); + // Send own MMC masked-write subcommand. + void SendMaskedWrite(unsigned char scmd, int track, bool V); usX2Y_volume_t Volume[5]; - char MuteInputMonitor, - Mute, - SelectInputMonitor, - Select; Cus428_ctls *us428_ctls; + // To hold channel light-mode states. + unsigned char + MuteInputMonitor, *Mute, + SoloInputMonitor, *Solo, + RecInputMonitor, *Rec, + SelectInputMonitor, *Select; + // The current selected bank, maximum number of bank/layers. + int aBank, cBanks; // Differential wheel tracking. int W0; // Some way to convert wheel (absolute) position into hh:mm:ss:ff:fr @@ -140,16 +173,20 @@ protected: int aWheel_R; // SET knob state. bool bSetLocate; + // REC knob state. + bool bSetRecord; // Last/current transport state. unsigned char uTransport; // Shuttle wheel absolute speed. int aWheelSpeed; + // The official number of faders (channels per bank) + int Y; }; class Cus428StateMixxx: public Cus428State{ public: - Cus428StateMixxx(struct us428ctls_sharedmem* Pus428ctls_sharedmem); + Cus428StateMixxx(struct us428ctls_sharedmem* Pus428ctls_sharedmem, int y); void UserKnobChangedTo(eKnobs K, bool V); void UserSliderChangedTo(int S, unsigned char New); void UserWheelChangedTo(E_In84 W, char Diff); diff -dupr us428control-0.4.4-0/us428control.cc us428control-0.4.5-5/us428control.cc --- us428control-0.4.4-0/us428control.cc 2006-12-07 14:27:24.000000000 +0000 +++ us428control-0.4.5-5/us428control.cc 2007-02-14 18:38:07.000000000 +0000 @@ -3,6 +3,7 @@ * Controller for Tascam US-X2Y * * Copyright (c) 2003 by Karsten Wiese + * Copyright (c) 2004-2007 by Rui Nuno Capela * * 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 @@ -63,7 +64,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("mode is one of (native, mixxx)\n"); + printf("mode is one of (us224, us428, mixxx)\n"); } /* * check the name id of the given hwdep handle @@ -85,7 +86,7 @@ static int check_hwinfo(snd_hwdep_t *hw, return 0; /* ok */ } -int US428Control(const char* DevName, int mode) +int US428Control(const char* DevName, int mode, int y) { snd_hwdep_t *hw; int err; @@ -95,7 +96,8 @@ int US428Control(const char* DevName, in int npfd, pollrc; if ((err = snd_hwdep_open(&hw, DevName, O_RDWR)) < 0) { - error("cannot open hwdep %s\n", DevName); + if (verbose > 1) + error("cannot open hwdep %s\n", DevName); return err; } @@ -105,6 +107,9 @@ int US428Control(const char* DevName, in return -ENODEV; } + if (verbose > 0) + fprintf(stderr, PROGNAME ": US-X2Y-compatible card found on hwdep %s\n", DevName); + Midi.CreatePorts(); npfd = snd_seq_poll_descriptors_count(Midi.Seq, POLLIN) + 1; @@ -118,11 +123,12 @@ int US428Control(const char* DevName, in snd_hwdep_close(hw); return -ENOMEM; } + us428ctls_sharedmem->CtlSnapShotRed = us428ctls_sharedmem->CtlSnapShotLast; if (mode == 1) - OneState = new Cus428StateMixxx(us428ctls_sharedmem); + OneState = new Cus428StateMixxx(us428ctls_sharedmem, y); else - OneState = new Cus428State(us428ctls_sharedmem); + OneState = new Cus428State(us428ctls_sharedmem, y); OneState->InitDevice(); @@ -131,7 +137,7 @@ int US428Control(const char* DevName, in if (verbose > 1 || pfds[0].revents & (POLLERR|POLLHUP)) printf("poll returned 0x%X\n", pfds[0].revents); if (pfds[0].revents & (POLLERR|POLLHUP)) - return -ENXIO; + return 0; /* -ENXIO; */ int Last = us428ctls_sharedmem->CtlSnapShotLast; if (verbose > 1) printf("Last is %i\n", Last); @@ -158,6 +164,7 @@ int US428Control(const char* DevName, in int main (int argc, char *argv[]) { int c; + int y = 8; int mode = 0; int card = -1; char *device_name = NULL, @@ -179,6 +186,12 @@ int main (int argc, char *argv[]) verbose = atoi(optarg); break; case 'm': + if (!strcmp(optarg, "us224")) + y = 4; + else + if (!strcmp(optarg, "us428")) + y = 8; + else if (!strcmp(optarg, "mixxx")) mode = 1; break; @@ -201,24 +214,28 @@ int main (int argc, char *argv[]) } } if (device_name) { - return US428Control(device_name, mode) != 0; + return US428Control(device_name, mode, y) != 0; } if (card >= 0) { sprintf(name, "hw:%d", card); - return US428Control(name, mode) != 0; + return US428Control(name, mode, y) != 0; } /* probe the all cards */ for (c = 0; c < SND_CARDS; c++) { // verbose--; sprintf(name, "hw:%d", c); - if (!US428Control(name, mode)) + if (US428Control(name, mode, y) == 0) { card = c; + break; + } } + if (card < 0) { fprintf(stderr, PROGNAME ": no US-X2Y-compatible cards found\n"); return 1; } + return 0; }