Changeset 1265

Show
Ignore:
Timestamp:
06/22/08 16:43:55 (13 years ago)
Author:
jwoithe
Message:

MOTU: major reworking of mixer dbus interface structure. Matrix mixers are used (where it makes sense) to greatly reduce the number of dbus nodes required to a number well below the default limit.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/motu/motu_avdevice.cpp

    r1257 r1265  
    248248 
    249249// Mixer registers 
     250const MatrixMixBus MixerBuses_Traveler[] = { 
     251    {"Mix 1", 0x4000, }, 
     252    {"Mix 2", 0x4100, }, 
     253    {"Mix 3", 0x4200, }, 
     254    {"Mix 4", 0x4300, }, 
     255}; 
     256 
     257const MatrixMixChannel MixerChannels_Traveler[] = { 
     258    {"Analog 1", MOTU_CTRL_STD_CHANNEL, 0x0000, }, 
     259    {"Analog 2", MOTU_CTRL_STD_CHANNEL, 0x0004, }, 
     260    {"Analog 3", MOTU_CTRL_STD_CHANNEL, 0x0008, }, 
     261    {"Analog 4", MOTU_CTRL_STD_CHANNEL, 0x000c, }, 
     262    {"Analog 5", MOTU_CTRL_STD_CHANNEL, 0x0010, }, 
     263    {"Analog 6", MOTU_CTRL_STD_CHANNEL, 0x0014, }, 
     264    {"Analog 7", MOTU_CTRL_STD_CHANNEL, 0x0018, }, 
     265    {"Analog 8", MOTU_CTRL_STD_CHANNEL, 0x001c, }, 
     266    {"AES/EBU 1", MOTU_CTRL_STD_CHANNEL, 0x0020, }, 
     267    {"AES/EBU 2", MOTU_CTRL_STD_CHANNEL, 0x0024, }, 
     268    {"SPDIF 1", MOTU_CTRL_STD_CHANNEL, 0x0028, }, 
     269    {"SPDIF 2", MOTU_CTRL_STD_CHANNEL, 0x002c, }, 
     270    {"ADAT 1", MOTU_CTRL_STD_CHANNEL, 0x0030, }, 
     271    {"ADAT 2", MOTU_CTRL_STD_CHANNEL, 0x0034, }, 
     272    {"ADAT 3", MOTU_CTRL_STD_CHANNEL, 0x0038, }, 
     273    {"ADAT 4", MOTU_CTRL_STD_CHANNEL, 0x003c, }, 
     274    {"ADAT 5", MOTU_CTRL_STD_CHANNEL, 0x0040, }, 
     275    {"ADAT 6", MOTU_CTRL_STD_CHANNEL, 0x0044, }, 
     276    {"ADAT 7", MOTU_CTRL_STD_CHANNEL, 0x0048, }, 
     277    {"ADAT 8", MOTU_CTRL_STD_CHANNEL, 0x004c, }, 
     278}; 
     279 
    250280const MixerCtrl MixerCtrls_Traveler[] = { 
    251     {"Mix1/Ana1_", "Mix 1 analog 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4000, }, 
    252     {"Mix1/Ana2_", "Mix 1 analog 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4004, }, 
    253     {"Mix1/Ana3_", "Mix 1 analog 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4008, }, 
    254     {"Mix1/Ana4_", "Mix 1 analog 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x400c, }, 
    255     {"Mix1/Ana5_", "Mix 1 analog 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4010, }, 
    256     {"Mix1/Ana6_", "Mix 1 analog 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4014, }, 
    257     {"Mix1/Ana7_", "Mix 1 analog 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4018, }, 
    258     {"Mix1/Ana8_", "Mix 1 analog 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x401c, }, 
    259     {"Mix1/Adat1_", "Mix 1 adat 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4030, }, 
    260     {"Mix1/Adat2_", "Mix 1 adat 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4034, }, 
    261     {"Mix1/Adat3_", "Mix 1 adat 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4038, }, 
    262     {"Mix1/Adat4_", "Mix 1 adat 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x403c, }, 
    263     {"Mix1/Adat5_", "Mix 1 adat 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4040, }, 
    264     {"Mix1/Adat6_", "Mix 1 adat 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4044, }, 
    265     {"Mix1/Adat7_", "Mix 1 adat 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4048, }, 
    266     {"Mix1/Adat8_", "Mix 1 adat 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x404c, }, 
    267     {"Mix1/Aes1_", "Mix 1 AES/EBU 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4020, }, 
    268     {"Mix1/Aes2_", "Mix 1 AES/EBU 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4024, }, 
    269     {"Mix1/Spdif1_", "Mix 1 SPDIF 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4028, }, 
    270     {"Mix1/Spdif2_", "Mix 1 SPDIF 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x402c, }, 
    271  
    272     {"Mix2/Ana1_", "Mix 2 analog 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4100, }, 
    273     {"Mix2/Ana2_", "Mix 2 analog 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4104, }, 
    274     {"Mix2/Ana3_", "Mix 2 analog 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4108, }, 
    275     {"Mix2/Ana4_", "Mix 2 analog 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x410c, }, 
    276     {"Mix2/Ana5_", "Mix 2 analog 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4110, }, 
    277     {"Mix2/Ana6_", "Mix 2 analog 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4114, }, 
    278     {"Mix2/Ana7_", "Mix 2 analog 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4118, }, 
    279     {"Mix2/Ana8_", "Mix 2 analog 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x411c, }, 
    280     {"Mix2/Adat1_", "Mix 2 adat 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4130, }, 
    281     {"Mix2/Adat2_", "Mix 2 adat 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4134, }, 
    282     {"Mix2/Adat3_", "Mix 2 adat 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4138, }, 
    283     {"Mix2/Adat4_", "Mix 2 adat 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x413c, }, 
    284     {"Mix2/Adat5_", "Mix 2 adat 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4140, }, 
    285     {"Mix2/Adat6_", "Mix 2 adat 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4144, }, 
    286     {"Mix2/Adat7_", "Mix 2 adat 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4148, }, 
    287     {"Mix2/Adat8_", "Mix 2 adat 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x414c, }, 
    288     {"Mix2/Aes1_", "Mix 2 AES/EBU 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4120, }, 
    289     {"Mix2/Aes2_", "Mix 2 AES/EBU 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4124, }, 
    290     {"Mix2/Spdif1_", "Mix 2 SPDIF 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4128, }, 
    291     {"Mix2/Spdif2_", "Mix 2 SPDIF 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x412c, }, 
    292  
    293     {"Mix3/Ana1_", "Mix 3 analog 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4200, }, 
    294     {"Mix3/Ana2_", "Mix 3 analog 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4204, }, 
    295     {"Mix3/Ana3_", "Mix 3 analog 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4208, }, 
    296     {"Mix3/Ana4_", "Mix 3 analog 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x420c, }, 
    297     {"Mix3/Ana5_", "Mix 3 analog 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4210, }, 
    298     {"Mix3/Ana6_", "Mix 3 analog 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4214, }, 
    299     {"Mix3/Ana7_", "Mix 3 analog 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4218, }, 
    300     {"Mix3/Ana8_", "Mix 3 analog 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x421c, }, 
    301     {"Mix3/Adat1_", "Mix 3 adat 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4230, }, 
    302     {"Mix3/Adat2_", "Mix 3 adat 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4234, }, 
    303     {"Mix3/Adat3_", "Mix 3 adat 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4238, }, 
    304     {"Mix3/Adat4_", "Mix 3 adat 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x423c, }, 
    305     {"Mix3/Adat5_", "Mix 3 adat 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4240, }, 
    306     {"Mix3/Adat6_", "Mix 3 adat 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4244, }, 
    307     {"Mix3/Adat7_", "Mix 3 adat 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4248, }, 
    308     {"Mix3/Adat8_", "Mix 3 adat 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x424c, }, 
    309     {"Mix3/Aes1_", "Mix 3 AES/EBU 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4220, }, 
    310     {"Mix3/Aes2_", "Mix 3 AES/EBU 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4224, }, 
    311     {"Mix3/Spdif1_", "Mix 3 SPDIF 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4228, }, 
    312     {"Mix3/Spdif2_", "Mix 3 SPDIF 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x422c, }, 
    313  
    314     {"Mix4/Ana1_", "Mix 4 analog 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4300, }, 
    315     {"Mix4/Ana2_", "Mix 4 analog 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4304, }, 
    316     {"Mix4/Ana3_", "Mix 4 analog 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4308, }, 
    317     {"Mix4/Ana4_", "Mix 4 analog 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x430c, }, 
    318     {"Mix4/Ana5_", "Mix 4 analog 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4310, }, 
    319     {"Mix4/Ana6_", "Mix 4 analog 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4314, }, 
    320     {"Mix4/Ana7_", "Mix 4 analog 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4318, }, 
    321     {"Mix4/Ana8_", "Mix 4 analog 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x431c, }, 
    322     {"Mix4/Adat1_", "Mix 4 adat 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4330, }, 
    323     {"Mix4/Adat2_", "Mix 4 adat 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4334, }, 
    324     {"Mix4/Adat3_", "Mix 4 adat 3 ", "", MOTU_CTRL_STD_CHANNEL, 0x4338, }, 
    325     {"Mix4/Adat4_", "Mix 4 adat 4 ", "", MOTU_CTRL_STD_CHANNEL, 0x433c, }, 
    326     {"Mix4/Adat5_", "Mix 4 adat 5 ", "", MOTU_CTRL_STD_CHANNEL, 0x4340, }, 
    327     {"Mix4/Adat6_", "Mix 4 adat 6 ", "", MOTU_CTRL_STD_CHANNEL, 0x4344, }, 
    328     {"Mix4/Adat7_", "Mix 4 adat 7 ", "", MOTU_CTRL_STD_CHANNEL, 0x4348, }, 
    329     {"Mix4/Adat8_", "Mix 4 adat 8 ", "", MOTU_CTRL_STD_CHANNEL, 0x434c, }, 
    330     {"Mix4/Aes1_", "Mix 4 AES/EBU 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4320, }, 
    331     {"Mix4/Aes2_", "Mix 4 AES/EBU 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x4324, }, 
    332     {"Mix4/Spdif1_", "Mix 4 SPDIF 1 ", "", MOTU_CTRL_STD_CHANNEL, 0x4328, }, 
    333     {"Mix4/Spdif2_", "Mix 4 SPDIF 2 ", "", MOTU_CTRL_STD_CHANNEL, 0x432c, }, 
    334  
    335281    {"Mix1/Mix_", "Mix 1 ", "", MOTU_CTRL_STD_MIX, 0x0c20, }, 
    336282    {"Mix2/Mix_", "Mix 2 ", "", MOTU_CTRL_STD_MIX, 0x0c24, }, 
     
    348294    {"Control/Ana8_", "Analog 8 input ", "", MOTU_CTRL_TRAVELER_LINE_INPUT_CTRLS, 7}, 
    349295 
     296    /* For phones source control, "register" is currently unused */ 
    350297    {"Control/Phones_", "Phones source", "", MOTU_CTRL_PHONES_SRC, 0}, 
    351298 
     299    /* For optical mode controls, the "register" is used to indicate direction */ 
    352300    {"Control/OpticalIn_mode", "Optical input mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_IN}, 
    353301    {"Control/OpticalOut_mode", "Optical output mode ", "", MOTU_CTRL_OPTICAL_MODE, MOTU_DIR_OUT}, 
    354302}; 
     303 
     304const MotuMixer Mixer_Traveler = MOTUMIXER( 
     305    MixerCtrls_Traveler, MixerBuses_Traveler, MixerChannels_Traveler); 
    355306 
    356307// For convenience during initial testing, just make the 828MkII and 896HD 
     
    358309// models will come once the final mixer structure is in place.  For now 
    359310// it's in a state of flux and subject to significant change. 
    360 #define MixerCtrls_828MkII MixerCtrls_Traveler 
    361 #define MixerCtrls_896HD   MixerCtrls_Traveler 
     311#define Mixer_828MkII Mixer_Traveler 
     312#define Mixer_896HD   Mixer_Traveler 
    362313 
    363314/* The order of DevicesProperty entries must match the numeric order of the 
     
    365316 */ 
    366317const DevicePropertyEntry DevicesProperty[] = { 
    367 //  { Ports_map,       N_ELEMENTS( Ports_map ),        MaxSR }, 
    368     { Ports_828MKII,   N_ELEMENTS( Ports_828MKII ),    96000, MixerCtrls_828MkII, N_ELEMENTS(MixerCtrls_828MkII), }, 
    369     { Ports_TRAVELER,  N_ELEMENTS( Ports_TRAVELER ),  192000, MixerCtrls_Traveler, N_ELEMENTS(MixerCtrls_Traveler), }, 
     318//  { Ports_map,       N_ELEMENTS( Ports_map ),        MaxSR, MixerDescrPtr }, 
     319    { Ports_828MKII,   N_ELEMENTS( Ports_828MKII ),    96000, &Mixer_828MkII, }, 
     320    { Ports_TRAVELER,  N_ELEMENTS( Ports_TRAVELER ),  192000, &Mixer_Traveler, }, 
    370321    { Ports_ULTRALITE, N_ELEMENTS( Ports_ULTRALITE ),  96000 }, 
    371322    { Ports_8PRE,      N_ELEMENTS( Ports_8PRE ),       96000 }, 
    372323    { Ports_828MKI,    N_ELEMENTS( Ports_828MKI ),     48000 }, 
    373     { Ports_896HD,     N_ELEMENTS( Ports_896HD ),     192000, MixerCtrls_896HD, N_ELEMENTS(MixerCtrls_896HD), }, 
     324    { Ports_896HD,     N_ELEMENTS( Ports_896HD ),     192000, &Mixer_896HD, }, 
    374325}; 
    375326 
     
    410361    unsigned int i; 
    411362    bool result = true; 
     363    MotuMatrixMixer *fader_mmixer = NULL; 
     364    MotuMatrixMixer *pan_mmixer = NULL; 
     365    MotuMatrixMixer *solo_mmixer = NULL; 
     366    MotuMatrixMixer *mute_mmixer = NULL; 
     367    unsigned int bus, ch; 
    412368    debugOutput(DEBUG_LEVEL_VERBOSE, "Building a MOTU mixer...\n"); 
    413369 
     
    421377    } 
    422378 
    423     // Mixer controls get added here 
    424     for (i=0; i<DevicesProperty[m_motu_model-1].n_mixer_ctrls; i++) { 
    425         unsigned int type = DevicesProperty[m_motu_model-1].mixer_ctrl[i].type; 
     379    /* Create the matrix mixers and populate them */ 
     380    fader_mmixer = new ChannelFaderMatrixMixer(*this, "fader"); 
     381    result &= m_MixerContainer->addElement(fader_mmixer); 
     382    pan_mmixer = new ChannelPanMatrixMixer(*this, "pan"); 
     383    result &= m_MixerContainer->addElement(pan_mmixer); 
     384    solo_mmixer = new ChannelBinSwMatrixMixer(*this, "solo",  
     385        MOTU_CTRL_MASK_SOLO_VALUE, MOTU_CTRL_MASK_SOLO_SETENABLE); 
     386    result &= m_MixerContainer->addElement(solo_mmixer); 
     387    mute_mmixer = new ChannelBinSwMatrixMixer(*this, "mute", 
     388        MOTU_CTRL_MASK_MUTE_VALUE, MOTU_CTRL_MASK_MUTE_SETENABLE); 
     389    result &= m_MixerContainer->addElement(mute_mmixer); 
     390    const struct MatrixMixBus *buses = DevicesProperty[m_motu_model-1].mixer->mixer_buses; 
     391    for (bus=0; bus<DevicesProperty[m_motu_model-1].mixer->n_mixer_buses; bus++) { 
     392        fader_mmixer->addRowInfo(buses[bus].name, 0, buses[bus].address); 
     393        pan_mmixer->addRowInfo(buses[bus].name, 0, buses[bus].address); 
     394        solo_mmixer->addRowInfo(buses[bus].name, 0, buses[bus].address); 
     395        mute_mmixer->addRowInfo(buses[bus].name, 0, buses[bus].address); 
     396    } 
     397    const struct MatrixMixChannel *channels = DevicesProperty[m_motu_model-1].mixer->mixer_channels; 
     398    for (ch=0; ch<DevicesProperty[m_motu_model-1].mixer->n_mixer_channels; ch++) { 
     399        uint32_t flags = channels[ch].flags; 
     400        if (flags & MOTU_CTRL_CHANNEL_FADER) 
     401            fader_mmixer->addColInfo(channels[ch].name, 0, channels[ch].addr_ofs); 
     402        if (flags & MOTU_CTRL_CHANNEL_PAN) 
     403            pan_mmixer->addColInfo(channels[ch].name, 0, channels[ch].addr_ofs); 
     404        if (flags & MOTU_CTRL_CHANNEL_SOLO) 
     405            solo_mmixer->addColInfo(channels[ch].name, 0, channels[ch].addr_ofs); 
     406        if (flags & MOTU_CTRL_CHANNEL_MUTE) 
     407            mute_mmixer->addColInfo(channels[ch].name, 0, channels[ch].addr_ofs); 
     408        flags &= ~(MOTU_CTRL_CHANNEL_FADER|MOTU_CTRL_CHANNEL_PAN|MOTU_CTRL_CHANNEL_SOLO|MOTU_CTRL_CHANNEL_MUTE); 
     409        if (flags) { 
     410            debugOutput(DEBUG_LEVEL_VERBOSE, "Control %s: unknown flag bits 0x%08x\n", channels[ch].name, flags); 
     411        } 
     412    } 
     413 
     414    // Single non-matrixed mixer controls get added here.  Channel controls are supported 
     415    // here, but usually these will be a part of a matrix mixer. 
     416    for (i=0; i<DevicesProperty[m_motu_model-1].mixer->n_mixer_ctrls; i++) { 
     417        const struct MixerCtrl *ctrl = &DevicesProperty[m_motu_model-1].mixer->mixer_ctrl[i]; 
     418        unsigned int type = ctrl->type; 
    426419        char name[100]; 
    427420        char label[100]; 
    428421        if (type & MOTU_CTRL_CHANNEL_FADER) { 
    429             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "fader"); 
    430             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"fader"); 
     422            snprintf(name, 100, "%s%s", ctrl->name, "fader"); 
     423            snprintf(label,100, "%s%s", ctrl->label,"fader"); 
    431424            result &= m_MixerContainer->addElement( 
    432                 new ChannelFader(*this,  
    433                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
    434                     name, label,  
    435                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     425                new ChannelFader(*this, ctrl->dev_register, name, label, ctrl->desc)); 
    436426            type &= ~MOTU_CTRL_CHANNEL_FADER; 
    437427        } 
    438428        if (type & MOTU_CTRL_CHANNEL_PAN) { 
    439             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "pan"); 
    440             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"pan"); 
     429            snprintf(name, 100, "%s%s", ctrl->name, "pan"); 
     430            snprintf(label,100, "%s%s", ctrl->label,"pan"); 
    441431            result &= m_MixerContainer->addElement( 
    442432                new ChannelPan(*this,  
    443                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
     433                    ctrl->dev_register, 
    444434                    name, label, 
    445                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     435                    ctrl->desc)); 
    446436            type &= ~MOTU_CTRL_CHANNEL_PAN; 
    447437        } 
    448438        if (type & MOTU_CTRL_CHANNEL_MUTE) { 
    449             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "mute"); 
    450             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"mute"); 
     439            snprintf(name, 100, "%s%s", ctrl->name, "mute"); 
     440            snprintf(label,100, "%s%s", ctrl->label,"mute"); 
    451441            result &= m_MixerContainer->addElement( 
    452                 new MotuBinarySwitch(*this,  
    453                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
     442                new MotuBinarySwitch(*this, ctrl->dev_register, 
    454443                    MOTU_CTRL_MASK_MUTE_VALUE, MOTU_CTRL_MASK_MUTE_SETENABLE, 
    455                     name, label, 
    456                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     444                    name, label, ctrl->desc)); 
    457445            type &= ~MOTU_CTRL_CHANNEL_MUTE; 
    458446        } 
    459447        if (type & MOTU_CTRL_CHANNEL_SOLO) { 
    460             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "solo"); 
    461             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"solo"); 
     448            snprintf(name, 100, "%s%s", ctrl->name, "solo"); 
     449            snprintf(label,100, "%s%s", ctrl->label,"solo"); 
    462450            result &= m_MixerContainer->addElement( 
    463                 new MotuBinarySwitch(*this,  
    464                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
     451                new MotuBinarySwitch(*this, ctrl->dev_register, 
    465452                    MOTU_CTRL_MASK_SOLO_VALUE, MOTU_CTRL_MASK_SOLO_SETENABLE, 
    466                     name, label, 
    467                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     453                    name, label, ctrl->desc)); 
    468454            type &= ~MOTU_CTRL_CHANNEL_SOLO; 
    469455        } 
    470456 
    471457        if (type & MOTU_CTRL_MIX_FADER) { 
    472             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "fader"); 
    473             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"fader"); 
     458            snprintf(name, 100, "%s%s", ctrl->name, "fader"); 
     459            snprintf(label,100, "%s%s", ctrl->label,"fader"); 
    474460            result &= m_MixerContainer->addElement( 
    475                 new MixFader(*this,  
    476                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
    477                     name, label,  
    478                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     461                new MixFader(*this, ctrl->dev_register, name, label, ctrl->desc)); 
    479462            type &= ~MOTU_CTRL_MIX_FADER; 
    480463        } 
    481464        if (type & MOTU_CTRL_MIX_MUTE) { 
    482             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "mute"); 
    483             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"mute"); 
     465            snprintf(name, 100, "%s%s", ctrl->name, "mute"); 
     466            snprintf(label,100, "%s%s", ctrl->label,"mute"); 
    484467            result &= m_MixerContainer->addElement( 
    485                 new MixMute(*this,  
    486                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
    487                     name, label, 
    488                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     468                new MixMute(*this, ctrl->dev_register, name, label, ctrl->desc)); 
    489469            type &= ~MOTU_CTRL_MIX_MUTE; 
    490470        } 
    491471        if (type & MOTU_CTRL_MIX_DEST) { 
    492             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "dest"); 
    493             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"dest"); 
     472            snprintf(name, 100, "%s%s", ctrl->name, "dest"); 
     473            snprintf(label,100, "%s%s", ctrl->label,"dest"); 
    494474            result &= m_MixerContainer->addElement( 
    495                 new MixDest(*this,  
    496                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
    497                     name, label, 
    498                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     475                new MixDest(*this, ctrl->dev_register, name, label, ctrl->desc)); 
    499476            type &= ~MOTU_CTRL_MIX_DEST; 
    500477        } 
    501478 
    502479        if (type & MOTU_CTRL_INPUT_TRIMGAIN) { 
    503             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "trimgain"); 
    504             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"trimgain"); 
     480            snprintf(name, 100, "%s%s", ctrl->name, "trimgain"); 
     481            snprintf(label,100, "%s%s", ctrl->label,"trimgain"); 
    505482            result &= m_MixerContainer->addElement( 
    506                 new InputGainPad(*this,  
    507                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, MOTU_CTRL_MODE_TRIMGAIN, 
    508                     name, label, 
    509                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     483                new InputGainPad(*this, ctrl->dev_register, MOTU_CTRL_MODE_TRIMGAIN, 
     484                    name, label, ctrl->desc)); 
    510485            type &= ~MOTU_CTRL_INPUT_TRIMGAIN; 
    511486        } 
    512487        if (type & MOTU_CTRL_INPUT_PAD) { 
    513             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "pad"); 
    514             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"pad"); 
     488            snprintf(name, 100, "%s%s", ctrl->name, "pad"); 
     489            snprintf(label,100, "%s%s", ctrl->label,"pad"); 
    515490            result &= m_MixerContainer->addElement( 
    516                 new InputGainPad(*this,  
    517                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, MOTU_CTRL_MODE_PAD, 
    518                     name, label, 
    519                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     491                new InputGainPad(*this, ctrl->dev_register, MOTU_CTRL_MODE_PAD, 
     492                    name, label, ctrl->desc)); 
    520493            type &= ~MOTU_CTRL_INPUT_PAD; 
    521494        } 
    522495 
    523496        if (type & MOTU_CTRL_INPUT_LEVEL) { 
    524             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "level"); 
    525             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"level"); 
     497            snprintf(name, 100, "%s%s", ctrl->name, "level"); 
     498            snprintf(label,100, "%s%s", ctrl->label,"level"); 
    526499            result &= m_MixerContainer->addElement( 
    527                 new MotuBinarySwitch(*this,  
    528                     MOTU_REG_INPUT_LEVEL, 
    529                     1<<DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 0, 
    530                     name, label, 
    531                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     500                new MotuBinarySwitch(*this, MOTU_REG_INPUT_LEVEL, 
     501                    1<<ctrl->dev_register, 0, name, label, ctrl->desc)); 
    532502            type &= ~MOTU_CTRL_INPUT_LEVEL; 
    533503        } 
    534504        if (type & MOTU_CTRL_INPUT_BOOST) { 
    535             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "boost"); 
    536             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"boost"); 
     505            snprintf(name, 100, "%s%s", ctrl->name, "boost"); 
     506            snprintf(label,100, "%s%s", ctrl->label,"boost"); 
    537507            result &= m_MixerContainer->addElement( 
    538                 new MotuBinarySwitch(*this,  
    539                     MOTU_REG_INPUT_BOOST, 
    540                     1<<DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 0, 
    541                     name, label, 
    542                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     508                new MotuBinarySwitch(*this, MOTU_REG_INPUT_BOOST, 
     509                    1<<ctrl->dev_register, 0, name, label, ctrl->desc)); 
    543510            type &= ~MOTU_CTRL_INPUT_BOOST; 
    544511        } 
    545512        if (type & MOTU_CTRL_PHONES_SRC) { 
    546             snprintf(name, 100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, "src"); 
    547             snprintf(label,100, "%s%s", DevicesProperty[m_motu_model-1].mixer_ctrl[i].label,"src"); 
     513            snprintf(name, 100, "%s%s", ctrl->name, "src"); 
     514            snprintf(label,100, "%s%s", ctrl->label,"src"); 
    548515            result &= m_MixerContainer->addElement( 
    549                 new PhonesSrc(*this,  
    550                     name, label, 
    551                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     516                new PhonesSrc(*this, name, label, ctrl->desc)); 
    552517            type &= ~MOTU_CTRL_PHONES_SRC; 
    553518        } 
    554519        if (type & MOTU_CTRL_OPTICAL_MODE) { 
    555520            result &= m_MixerContainer->addElement( 
    556                 new OpticalMode(*this, DevicesProperty[m_motu_model-1].mixer_ctrl[i].dev_register, 
    557                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].name, 
    558                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].label, 
    559                     DevicesProperty[m_motu_model-1].mixer_ctrl[i].desc)); 
     521                new OpticalMode(*this, ctrl->dev_register, 
     522                    ctrl->name, ctrl->label, ctrl->desc)); 
    560523            type &= ~MOTU_CTRL_OPTICAL_MODE; 
    561524        } 
    562525 
    563526        if (type) { 
    564             debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown mixer control type flag bits 0x%08x\n", DevicesProperty[m_motu_model-1].mixer_ctrl[i].type); 
     527            debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown mixer control type flag bits 0x%08x\n", ctrl->type); 
    565528        } 
    566529    } 
  • trunk/libffado/src/motu/motu_avdevice.h

    r1239 r1265  
    130130}; 
    131131 
     132struct MatrixMixBus { 
     133    const char *name; 
     134    unsigned int address; 
     135}; 
     136 
     137struct MatrixMixChannel { 
     138    const char *name; 
     139    unsigned int flags; 
     140    unsigned int addr_ofs; 
     141}; 
     142 
     143struct MotuMixer { 
     144    const MixerCtrl *mixer_ctrl; 
     145    unsigned int n_mixer_ctrls; 
     146    const MatrixMixBus *mixer_buses; 
     147    unsigned int n_mixer_buses; 
     148    const MatrixMixChannel *mixer_channels; 
     149    unsigned int n_mixer_channels; 
     150}; 
     151 
    132152struct DevicePropertyEntry { 
    133153    const PortEntry* port_entry; 
    134154    unsigned int n_port_entries; 
    135155    signed int MaxSampleRate; 
    136     const MixerCtrl *mixer_ctrl; 
    137     unsigned int n_mixer_ctrls; 
     156    const struct MotuMixer *mixer; 
    138157    // Others features can be added here like MIDI port presence. 
    139158}; 
     
    141160/* Macro to calculate the size of an array */ 
    142161#define N_ELEMENTS(_array) (sizeof(_array) / sizeof((_array)[0])) 
     162 
     163/* Macro to define a MotuMixer structure succintly */ 
     164#define MOTUMIXER(_ctrls, _buses, _channels) \ 
     165    { _ctrls, N_ELEMENTS(_ctrls), _buses, N_ELEMENTS(_buses), _channels, N_ELEMENTS(_channels), } 
    143166 
    144167class MotuDevice : public FFADODevice { 
  • trunk/libffado/src/motu/motu_controls.cpp

    r1158 r1265  
    187187} 
    188188 
     189 
     190MotuMatrixMixer::MotuMatrixMixer(MotuDevice &parent) 
     191: Control::MatrixMixer(&parent, "MatrixMixer") 
     192, m_parent(parent) 
     193{ 
     194} 
     195 
     196MotuMatrixMixer::MotuMatrixMixer(MotuDevice &parent, std::string name) 
     197: Control::MatrixMixer(&parent, name) 
     198, m_parent(parent) 
     199{ 
     200} 
     201 
     202void MotuMatrixMixer::addRowInfo(std::string name, unsigned int flags,  
     203  unsigned int address) 
     204{ 
     205    struct sSignalInfo s; 
     206    s.name = name; 
     207    s.flags = flags; 
     208    s.address = address; 
     209    m_RowInfo.push_back(s); 
     210} 
     211 
     212void MotuMatrixMixer::addColInfo(std::string name, unsigned int flags,  
     213  unsigned int address) 
     214{ 
     215    struct sSignalInfo s; 
     216    s.name = name; 
     217    s.flags = flags; 
     218    s.address = address; 
     219    m_ColInfo.push_back(s); 
     220} 
     221 
     222uint32_t MotuMatrixMixer::getCellRegister(const unsigned int row, const unsigned int col) 
     223{ 
     224    return m_RowInfo.at(row).address + m_ColInfo.at(col).address; 
     225} 
     226 
     227void MotuMatrixMixer::show() 
     228{ 
     229    debugOutput(DEBUG_LEVEL_NORMAL, "MOTU matrix mixer\n"); 
     230} 
     231 
     232std::string MotuMatrixMixer::getRowName(const int row) 
     233{ 
     234    return m_RowInfo.at(row).name; 
     235} 
     236 
     237std::string MotuMatrixMixer::getColName(const int col) 
     238{ 
     239    return m_ColInfo.at(col).name; 
     240} 
     241 
     242int MotuMatrixMixer::getRowCount() 
     243{ 
     244    return m_RowInfo.size(); 
     245} 
     246 
     247int MotuMatrixMixer::getColCount() 
     248{ 
     249    return m_ColInfo.size(); 
     250} 
     251 
     252ChannelFaderMatrixMixer::ChannelFaderMatrixMixer(MotuDevice &parent) 
     253: MotuMatrixMixer(parent, "ChannelFaderMatrixMixer") 
     254{ 
     255} 
     256 
     257ChannelFaderMatrixMixer::ChannelFaderMatrixMixer(MotuDevice &parent, std::string name) 
     258: MotuMatrixMixer(parent, name) 
     259{ 
     260} 
     261 
     262double ChannelFaderMatrixMixer::setValue(const int row, const int col, const double val) 
     263{ 
     264    uint32_t v; 
     265    v = val<0?0:(uint32_t)val; 
     266    if (v > 0x80) 
     267      v = 0x80; 
     268    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelFader setValue for row %d col %d to %lf (%ld)\n", 
     269      row, col, val, v); 
     270 
     271    // Bit 30 indicates that the channel fader is being set 
     272    v |= 0x40000000; 
     273    m_parent.WriteRegister(getCellRegister(row,col), v); 
     274 
     275    return true; 
     276} 
     277 
     278double ChannelFaderMatrixMixer::getValue(const int row, const int col) 
     279{ 
     280    uint32_t val; 
     281    // FIXME: we could just read the appropriate mixer status field from the 
     282    // receive stream processor once we work out an efficient way to do this. 
     283    val = m_parent.ReadRegister(getCellRegister(row,col)) & 0xff; 
     284 
     285    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelFader getValue for row %d col %d = %lu\n", 
     286      row, col, val); 
     287    return val; 
     288} 
     289 
     290ChannelPanMatrixMixer::ChannelPanMatrixMixer(MotuDevice &parent) 
     291: MotuMatrixMixer(parent, "ChannelPanMatrixMixer") 
     292{ 
     293} 
     294 
     295ChannelPanMatrixMixer::ChannelPanMatrixMixer(MotuDevice &parent, std::string name) 
     296: MotuMatrixMixer(parent, name) 
     297{ 
     298} 
     299 
     300double ChannelPanMatrixMixer::setValue(const int row, const int col, const double val) 
     301{ 
     302    uint32_t v; 
     303    v = ((val<-64?-64:(int32_t)val)+64) & 0xff; 
     304    if (v > 0x80) 
     305      v = 0x80; 
     306 
     307    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelPan setValue for row %d col %d to %lf (%ld)\n", 
     308      row, col, val, v); 
     309 
     310    // Bit 31 indicates that pan is being set 
     311    v = (v << 8) | 0x80000000; 
     312    m_parent.WriteRegister(getCellRegister(row,col), v); 
     313 
     314    return true; 
     315} 
     316 
     317double ChannelPanMatrixMixer::getValue(const int row, const int col) 
     318{ 
     319    int32_t val; 
     320    // FIXME: we could just read the appropriate mixer status field from the 
     321    // receive stream processor once we work out an efficient way to do this. 
     322    val = m_parent.ReadRegister(getCellRegister(row,col)); 
     323    val = ((val >> 8) & 0xff) - 0x40; 
     324 
     325    debugOutput(DEBUG_LEVEL_VERBOSE, "ChannelPan getValue for row %d col %d = %lu\n", 
     326      row, col, val); 
     327    return val; 
     328} 
     329 
     330ChannelBinSwMatrixMixer::ChannelBinSwMatrixMixer(MotuDevice &parent) 
     331: MotuMatrixMixer(parent, "ChannelPanMatrixMixer") 
     332, m_value_mask(0) 
     333, m_setenable_mask(0) 
     334{ 
     335} 
     336 
     337/* If no "write enable" is implemented for a given switch it's safe to  
     338 * pass zero in to setenable_mask. 
     339 */ 
     340ChannelBinSwMatrixMixer::ChannelBinSwMatrixMixer(MotuDevice &parent, std::string name, 
     341  unsigned int val_mask, unsigned int setenable_mask) 
     342: MotuMatrixMixer(parent, name) 
     343, m_value_mask(val_mask) 
     344, m_setenable_mask(setenable_mask) 
     345{ 
     346} 
     347 
     348double ChannelBinSwMatrixMixer::setValue(const int row, const int col, const double val) 
     349{ 
     350    uint32_t v; 
     351 
     352    debugOutput(DEBUG_LEVEL_VERBOSE, "BinSw setValue for row %d col %d to %lf (%ld)\n", 
     353      row, col, val, val==0?0:1); 
     354 
     355    // Set the value 
     356    if (m_setenable_mask) { 
     357      v = (val==0)?0:m_value_mask; 
     358      // Set the "write enable" bit for the value being set 
     359      v |= m_setenable_mask; 
     360    } else { 
     361      // It would be good to utilise the cached value from the receive 
     362      // processor (if running) later on.  For now we'll just fetch the 
     363      // current register value directly when needed. 
     364      v = m_parent.ReadRegister(getCellRegister(row,col)); 
     365      if (v==0) 
     366        v &= ~m_value_mask; 
     367      else 
     368        v |= m_value_mask; 
     369    } 
     370    m_parent.WriteRegister(getCellRegister(row,col), v); 
     371 
     372    return true; 
     373} 
     374 
     375double ChannelBinSwMatrixMixer::getValue(const int row, const int col) 
     376{ 
     377    uint32_t val; 
     378 
     379    // FIXME: we could just read the appropriate mixer status field from the  
     380    // receive stream processor once we work out an efficient way to do this. 
     381    val = m_parent.ReadRegister(getCellRegister(row,col)); 
     382    val = (val & m_value_mask) != 0; 
     383 
     384    debugOutput(DEBUG_LEVEL_VERBOSE, "BinSw getValue for row %d col %d = %lu\n", 
     385      row, col, val); 
     386    return val; 
     387} 
     388 
     389 
    189390MixFader::MixFader(MotuDevice &parent, unsigned int dev_reg) 
    190391: MotuDiscreteCtrl(parent, dev_reg) 
  • trunk/libffado/src/motu/motu_controls.h

    r1158 r1265  
    150150}; 
    151151 
     152class MotuMatrixMixer : public Control::MatrixMixer 
     153{ 
     154public: 
     155    MotuMatrixMixer(MotuDevice &parent); 
     156    MotuMatrixMixer(MotuDevice &parent, std::string name); 
     157    virtual ~MotuMatrixMixer() {}; 
     158 
     159    void addRowInfo(std::string name, unsigned int flags, unsigned int address); 
     160    void addColInfo(std::string name, unsigned int flags, unsigned int address); 
     161    uint32_t getCellRegister(const unsigned int row, const unsigned int col); 
     162 
     163    virtual void show(); 
     164 
     165    virtual std::string getRowName(const int row); 
     166    virtual std::string getColName(const int col); 
     167    virtual int canWrite( const int, const int ) { return true; } 
     168    virtual int getRowCount(); 
     169    virtual int getColCount(); 
     170 
     171protected: 
     172     struct sSignalInfo { 
     173         std::string name; 
     174         unsigned int flags; 
     175         unsigned int address; 
     176     }; 
     177 
     178     std::vector<struct sSignalInfo> m_RowInfo; 
     179     std::vector<struct sSignalInfo> m_ColInfo; 
     180 
     181     MotuDevice& m_parent; 
     182}; 
     183 
     184class ChannelFaderMatrixMixer : public MotuMatrixMixer 
     185{ 
     186public: 
     187    ChannelFaderMatrixMixer(MotuDevice &parent); 
     188    ChannelFaderMatrixMixer(MotuDevice &parent, std::string name); 
     189    virtual double setValue(const int row, const int col, const double val); 
     190    virtual double getValue(const int row, const int col); 
     191}; 
     192 
     193class ChannelPanMatrixMixer : public MotuMatrixMixer 
     194{ 
     195public: 
     196    ChannelPanMatrixMixer(MotuDevice &parent); 
     197    ChannelPanMatrixMixer(MotuDevice &parent, std::string name); 
     198    virtual double setValue(const int row, const int col, const double val); 
     199    virtual double getValue(const int row, const int col); 
     200}; 
     201 
     202class ChannelBinSwMatrixMixer : public MotuMatrixMixer 
     203{ 
     204public: 
     205    ChannelBinSwMatrixMixer(MotuDevice &parent); 
     206    ChannelBinSwMatrixMixer(MotuDevice &parent, std::string name,  
     207      unsigned int val_mask, unsigned int setenable_mask); 
     208    virtual double setValue(const int row, const int col, const double val); 
     209    virtual double getValue(const int row, const int col); 
     210 
     211protected: 
     212    unsigned int m_value_mask; 
     213    unsigned int m_setenable_mask; 
     214}; 
     215 
     216 
     217 
    152218class MixFader 
    153219    : public MotuDiscreteCtrl 
  • trunk/libffado/support/mixer/mixer_motu.py

    r1257 r1265  
    2929        MotuMixerUI.__init__(self,parent,name,fl) 
    3030 
    31     # public slot: channel/mix faders 
    32     def updateFader(self, a0): 
     31    # public slot: channel faders within a matrix mixer 
     32    def updateChannelFader(self, a0): 
    3333        sender = self.sender() 
    3434        vol = 128-a0 
    35         print "setting %s channel/mix fader to %d" % (self.ChannelFaders[sender][0], vol) 
    36         self.hw.setDiscrete(self.ChannelFaders[sender][0], vol) 
    37  
    38     # public slot: a generic multivalue control 
     35        print "setting %s for mix %d channel %d to %d" % (self.ChannelFaders[sender][0],  
     36            self.ChannelFaders[sender][1], self.ChannelFaders[sender][2], vol) 
     37        self.hw.setMatrixMixerValue(self.ChannelFaders[sender][0], 
     38            self.ChannelFaders[sender][1], self.ChannelFaders[sender][2], vol) 
     39 
     40    # public slot: a multivalue control within a matrix mixer 
     41    def updateChannelControl(self, a0): 
     42        sender = self.sender() 
     43        val = a0 
     44        print "setting %s for mix %d channel %d to %d" % (self.ChannelControls[sender][0],  
     45            self.ChannelControls[sender][1], self.ChannelControls[sender][2], val) 
     46        self.hw.setMatrixMixerValue(self.ChannelControls[sender][0],  
     47            self.ChannelControls[sender][1], self.ChannelControls[sender][2], val) 
     48 
     49    # public slot: a generic single multivalue control 
    3950    def updateControl(self, a0): 
    4051        sender = self.sender() 
     
    4354        self.hw.setDiscrete(self.Controls[sender][0], val) 
    4455 
    45     # public slot: generic binary switch 
     56    # public slot: a binary switch within a matrix mixer 
     57    def updateChannelBinarySwitch(self, a0): 
     58        sender = self.sender() 
     59        val=a0 
     60        print "setting %s for mix %d channel %d switch to %d" % (self.ChannelBinarySwitches[sender][0],  
     61            self.ChannelBinarySwitches[sender][1], self.ChannelBinarySwitches[sender][2], val) 
     62        self.hw.setMatrixMixerValue(self.ChannelBinarySwitches[sender][0],  
     63            self.ChannelBinarySwitches[sender][1], self.ChannelBinarySwitches[sender][2], val) 
     64 
     65    # public slot: generic single binary switch 
    4666    def updateBinarySwitch(self, a0): 
    4767        sender = self.sender() 
     
    4969        print "setting %s switch to %d" % (self.BinarySwitches[sender][0], val) 
    5070        self.hw.setDiscrete(self.BinarySwitches[sender][0], val) 
     71 
     72    # public slot: a faders (not in a matrix mixer) 
     73    def updateFader(self, a0): 
     74        sender = self.sender() 
     75        vol = 128-a0 
     76        print "setting %s mix fader to %d" % (self.Faders[sender][0], vol) 
     77        self.hw.setDiscrete(self.Faders[sender][0], vol) 
    5178 
    5279    # public slot: mix destination control 
     
    7097        print "Init MOTU mixer window" 
    7198 
     99        # For matrix mixer controls (channel faders, pans, solos, mutes) the 
     100        # first index (the row) is the zero-based mix number while the 
     101        # second index (the column) is the zero-based channel number.  The 
     102        # order of the channel enumeration must agree with that used when 
     103        # creating the dbus controls within motu_avdevice.cpp. 
    72104        self.ChannelFaders={ 
    73             self.mix1ana1_fader: ['/Mixer/Mix1/Ana1_fader'], 
    74             self.mix1ana2_fader: ['/Mixer/Mix1/Ana2_fader'], 
    75             self.mix1ana3_fader: ['/Mixer/Mix1/Ana3_fader'], 
    76             self.mix1ana4_fader: ['/Mixer/Mix1/Ana4_fader'], 
    77             self.mix1ana5_fader: ['/Mixer/Mix1/Ana5_fader'], 
    78             self.mix1ana6_fader: ['/Mixer/Mix1/Ana6_fader'], 
    79             self.mix1ana7_fader: ['/Mixer/Mix1/Ana7_fader'], 
    80             self.mix1ana8_fader: ['/Mixer/Mix1/Ana8_fader'], 
    81             self.mix1adat1_fader: ['/Mixer/Mix1/Adat1_fader'], 
    82             self.mix1adat2_fader: ['/Mixer/Mix1/Adat2_fader'], 
    83             self.mix1adat3_fader: ['/Mixer/Mix1/Adat3_fader'], 
    84             self.mix1adat4_fader: ['/Mixer/Mix1/Adat4_fader'], 
    85             self.mix1adat5_fader: ['/Mixer/Mix1/Adat5_fader'], 
    86             self.mix1adat6_fader: ['/Mixer/Mix1/Adat6_fader'], 
    87             self.mix1adat7_fader: ['/Mixer/Mix1/Adat7_fader'], 
    88             self.mix1adat8_fader: ['/Mixer/Mix1/Adat8_fader'], 
    89             self.mix1aes1_fader:  ['/Mixer/Mix1/Aes1_fader'], 
    90             self.mix1aes2_fader:  ['/Mixer/Mix1/Aes2_fader'], 
    91             self.mix1spdif1_fader: ['/Mixer/Mix1/Spdif1_fader'], 
    92             self.mix1spdif2_fader: ['/Mixer/Mix1/Spdif2_fader'], 
     105            self.mix1ana1_fader: ['/Mixer/fader', 0, 0], 
     106            self.mix1ana2_fader: ['/Mixer/fader', 0, 1], 
     107            self.mix1ana3_fader: ['/Mixer/fader', 0, 2], 
     108            self.mix1ana4_fader: ['/Mixer/fader', 0, 3], 
     109            self.mix1ana5_fader: ['/Mixer/fader', 0, 4], 
     110            self.mix1ana6_fader: ['/Mixer/fader', 0, 5], 
     111            self.mix1ana7_fader: ['/Mixer/fader', 0, 6], 
     112            self.mix1ana8_fader: ['/Mixer/fader', 0, 7], 
     113            self.mix1aes1_fader: ['/Mixer/fader', 0, 8], 
     114            self.mix1aes2_fader: ['/Mixer/fader', 0, 9], 
     115            self.mix1spdif1_fader: ['/Mixer/fader', 0, 10], 
     116            self.mix1spdif2_fader: ['/Mixer/fader', 0, 11], 
     117            self.mix1adat1_fader: ['/Mixer/fader', 0, 12], 
     118            self.mix1adat2_fader: ['/Mixer/fader', 0, 13], 
     119            self.mix1adat3_fader: ['/Mixer/fader', 0, 14], 
     120            self.mix1adat4_fader: ['/Mixer/fader', 0, 15], 
     121            self.mix1adat5_fader: ['/Mixer/fader', 0, 16], 
     122            self.mix1adat6_fader: ['/Mixer/fader', 0, 17], 
     123            self.mix1adat7_fader: ['/Mixer/fader', 0, 18], 
     124            self.mix1adat8_fader: ['/Mixer/fader', 0, 19], 
     125 
     126            self.mix2ana1_fader: ['/Mixer/fader', 1, 0], 
     127            self.mix2ana2_fader: ['/Mixer/fader', 1, 1], 
     128            self.mix2ana3_fader: ['/Mixer/fader', 1, 2], 
     129            self.mix2ana4_fader: ['/Mixer/fader', 1, 3], 
     130            self.mix2ana5_fader: ['/Mixer/fader', 1, 4], 
     131            self.mix2ana6_fader: ['/Mixer/fader', 1, 5], 
     132            self.mix2ana7_fader: ['/Mixer/fader', 1, 6], 
     133            self.mix2ana8_fader: ['/Mixer/fader', 1, 7], 
     134            self.mix2aes1_fader: ['/Mixer/fader', 1, 8], 
     135            self.mix2aes2_fader: ['/Mixer/fader', 1, 9], 
     136            self.mix2spdif1_fader: ['/Mixer/fader', 1, 10], 
     137            self.mix2spdif2_fader: ['/Mixer/fader', 1, 11], 
     138            self.mix2adat1_fader: ['/Mixer/fader', 1, 12], 
     139            self.mix2adat2_fader: ['/Mixer/fader', 1, 13], 
     140            self.mix2adat3_fader: ['/Mixer/fader', 1, 14], 
     141            self.mix2adat4_fader: ['/Mixer/fader', 1, 15], 
     142            self.mix2adat5_fader: ['/Mixer/fader', 1, 16], 
     143            self.mix2adat6_fader: ['/Mixer/fader', 1, 17], 
     144            self.mix2adat7_fader: ['/Mixer/fader', 1, 18], 
     145            self.mix2adat8_fader: ['/Mixer/fader', 1, 19], 
     146 
     147            self.mix3ana1_fader: ['/Mixer/fader', 2, 0], 
     148            self.mix3ana2_fader: ['/Mixer/fader', 2, 1], 
     149            self.mix3ana3_fader: ['/Mixer/fader', 2, 2], 
     150            self.mix3ana4_fader: ['/Mixer/fader', 2, 3], 
     151            self.mix3ana5_fader: ['/Mixer/fader', 2, 4], 
     152            self.mix3ana6_fader: ['/Mixer/fader', 2, 5], 
     153            self.mix3ana7_fader: ['/Mixer/fader', 2, 6], 
     154            self.mix3ana8_fader: ['/Mixer/fader', 2, 7], 
     155            self.mix3aes1_fader: ['/Mixer/fader', 2, 8], 
     156            self.mix3aes2_fader: ['/Mixer/fader', 2, 9], 
     157            self.mix3spdif1_fader: ['/Mixer/fader', 2, 10], 
     158            self.mix3spdif2_fader: ['/Mixer/fader', 2, 11], 
     159            self.mix3adat1_fader: ['/Mixer/fader', 2, 12], 
     160            self.mix3adat2_fader: ['/Mixer/fader', 2, 13], 
     161            self.mix3adat3_fader: ['/Mixer/fader', 2, 14], 
     162            self.mix3adat4_fader: ['/Mixer/fader', 2, 15], 
     163            self.mix3adat5_fader: ['/Mixer/fader', 2, 16], 
     164            self.mix3adat6_fader: ['/Mixer/fader', 2, 17], 
     165            self.mix3adat7_fader: ['/Mixer/fader', 2, 18], 
     166            self.mix3adat8_fader: ['/Mixer/fader', 2, 19], 
     167 
     168            self.mix4ana1_fader: ['/Mixer/fader', 3, 0], 
     169            self.mix4ana2_fader: ['/Mixer/fader', 3, 1], 
     170            self.mix4ana3_fader: ['/Mixer/fader', 3, 2], 
     171            self.mix4ana4_fader: ['/Mixer/fader', 3, 3], 
     172            self.mix4ana5_fader: ['/Mixer/fader', 3, 4], 
     173            self.mix4ana6_fader: ['/Mixer/fader', 3, 5], 
     174            self.mix4ana7_fader: ['/Mixer/fader', 3, 6], 
     175            self.mix4ana8_fader: ['/Mixer/fader', 3, 7], 
     176            self.mix4aes1_fader: ['/Mixer/fader', 3, 8], 
     177            self.mix4aes2_fader: ['/Mixer/fader', 3, 9], 
     178            self.mix4spdif1_fader: ['/Mixer/fader', 3, 10], 
     179            self.mix4spdif2_fader: ['/Mixer/fader', 3, 11], 
     180            self.mix4adat1_fader: ['/Mixer/fader', 3, 12], 
     181            self.mix4adat2_fader: ['/Mixer/fader', 3, 13], 
     182            self.mix4adat3_fader: ['/Mixer/fader', 3, 14], 
     183            self.mix4adat4_fader: ['/Mixer/fader', 3, 15], 
     184            self.mix4adat5_fader: ['/Mixer/fader', 3, 16], 
     185            self.mix4adat6_fader: ['/Mixer/fader', 3, 17], 
     186            self.mix4adat7_fader: ['/Mixer/fader', 3, 18], 
     187            self.mix4adat8_fader: ['/Mixer/fader', 3, 19], 
     188        } 
     189 
     190        self.Faders={ 
    93191            self.mix1_fader: ['/Mixer/Mix1/Mix_fader'], 
    94  
    95             self.mix2ana1_fader: ['/Mixer/Mix2/Ana1_fader'], 
    96             self.mix2ana2_fader: ['/Mixer/Mix2/Ana2_fader'], 
    97             self.mix2ana3_fader: ['/Mixer/Mix2/Ana3_fader'], 
    98             self.mix2ana4_fader: ['/Mixer/Mix2/Ana4_fader'], 
    99             self.mix2ana5_fader: ['/Mixer/Mix2/Ana5_fader'], 
    100             self.mix2ana6_fader: ['/Mixer/Mix2/Ana6_fader'], 
    101             self.mix2ana7_fader: ['/Mixer/Mix2/Ana7_fader'], 
    102             self.mix2ana8_fader: ['/Mixer/Mix2/Ana8_fader'], 
    103             self.mix2adat1_fader: ['/Mixer/Mix2/Adat1_fader'], 
    104             self.mix2adat2_fader: ['/Mixer/Mix2/Adat2_fader'], 
    105             self.mix2adat3_fader: ['/Mixer/Mix2/Adat3_fader'], 
    106             self.mix2adat4_fader: ['/Mixer/Mix2/Adat4_fader'], 
    107             self.mix2adat5_fader: ['/Mixer/Mix2/Adat5_fader'], 
    108             self.mix2adat6_fader: ['/Mixer/Mix2/Adat6_fader'], 
    109             self.mix2adat7_fader: ['/Mixer/Mix2/Adat7_fader'], 
    110             self.mix2adat8_fader: ['/Mixer/Mix2/Adat8_fader'], 
    111             self.mix2aes1_fader:  ['/Mixer/Mix2/Aes1_fader'], 
    112             self.mix2aes2_fader:  ['/Mixer/Mix2/Aes2_fader'], 
    113             self.mix2spdif1_fader: ['/Mixer/Mix2/Spdif1_fader'], 
    114             self.mix2spdif2_fader: ['/Mixer/Mix2/Spdif2_fader'], 
    115192            self.mix2_fader: ['/Mixer/Mix2/Mix_fader'], 
    116  
    117             self.mix3ana1_fader: ['/Mixer/Mix3/Ana1_fader'], 
    118             self.mix3ana2_fader: ['/Mixer/Mix3/Ana2_fader'], 
    119             self.mix3ana3_fader: ['/Mixer/Mix3/Ana3_fader'], 
    120             self.mix3ana4_fader: ['/Mixer/Mix3/Ana4_fader'], 
    121             self.mix3ana5_fader: ['/Mixer/Mix3/Ana5_fader'], 
    122             self.mix3ana6_fader: ['/Mixer/Mix3/Ana6_fader'], 
    123             self.mix3ana7_fader: ['/Mixer/Mix3/Ana7_fader'], 
    124             self.mix3ana8_fader: ['/Mixer/Mix3/Ana8_fader'], 
    125             self.mix3adat1_fader: ['/Mixer/Mix3/Adat1_fader'], 
    126             self.mix3adat2_fader: ['/Mixer/Mix3/Adat2_fader'], 
    127             self.mix3adat3_fader: ['/Mixer/Mix3/Adat3_fader'], 
    128             self.mix3adat4_fader: ['/Mixer/Mix3/Adat4_fader'], 
    129             self.mix3adat5_fader: ['/Mixer/Mix3/Adat5_fader'], 
    130             self.mix3adat6_fader: ['/Mixer/Mix3/Adat6_fader'], 
    131             self.mix3adat7_fader: ['/Mixer/Mix3/Adat7_fader'], 
    132             self.mix3adat8_fader: ['/Mixer/Mix3/Adat8_fader'], 
    133             self.mix3aes1_fader:  ['/Mixer/Mix3/Aes1_fader'], 
    134             self.mix3aes2_fader:  ['/Mixer/Mix3/Aes2_fader'], 
    135             self.mix3spdif1_fader: ['/Mixer/Mix3/Spdif1_fader'], 
    136             self.mix3spdif2_fader: ['/Mixer/Mix3/Spdif2_fader'], 
    137193            self.mix3_fader: ['/Mixer/Mix3/Mix_fader'], 
    138  
    139             self.mix4ana1_fader: ['/Mixer/Mix4/Ana1_fader'], 
    140             self.mix4ana2_fader: ['/Mixer/Mix4/Ana2_fader'], 
    141             self.mix4ana3_fader: ['/Mixer/Mix4/Ana3_fader'], 
    142             self.mix4ana4_fader: ['/Mixer/Mix4/Ana4_fader'], 
    143             self.mix4ana5_fader: ['/Mixer/Mix4/Ana5_fader'], 
    144             self.mix4ana6_fader: ['/Mixer/Mix4/Ana6_fader'], 
    145             self.mix4ana7_fader: ['/Mixer/Mix4/Ana7_fader'], 
    146             self.mix4ana8_fader: ['/Mixer/Mix4/Ana8_fader'], 
    147             self.mix4adat1_fader: ['/Mixer/Mix4/Adat1_fader'], 
    148             self.mix4adat2_fader: ['/Mixer/Mix4/Adat2_fader'], 
    149             self.mix4adat3_fader: ['/Mixer/Mix4/Adat3_fader'], 
    150             self.mix4adat4_fader: ['/Mixer/Mix4/Adat4_fader'], 
    151             self.mix4adat5_fader: ['/Mixer/Mix4/Adat5_fader'], 
    152             self.mix4adat6_fader: ['/Mixer/Mix4/Adat6_fader'], 
    153             self.mix4adat7_fader: ['/Mixer/Mix4/Adat7_fader'], 
    154             self.mix4adat8_fader: ['/Mixer/Mix4/Adat8_fader'], 
    155             self.mix4aes1_fader:  ['/Mixer/Mix4/Aes1_fader'], 
    156             self.mix4aes2_fader:  ['/Mixer/Mix4/Aes2_fader'], 
    157             self.mix4spdif1_fader: ['/Mixer/Mix4/Spdif1_fader'], 
    158             self.mix4spdif2_fader: ['/Mixer/Mix4/Spdif2_fader'], 
    159194            self.mix4_fader: ['/Mixer/Mix4/Mix_fader'], 
    160             } 
     195        } 
     196 
     197        self.ChannelControls={ 
     198            self.mix1ana1_pan:   ['/Mixer/pan', 0, 0], 
     199            self.mix1ana2_pan:   ['/Mixer/pan', 0, 1], 
     200            self.mix1ana3_pan:   ['/Mixer/pan', 0, 2], 
     201            self.mix1ana4_pan:   ['/Mixer/pan', 0, 3], 
     202            self.mix1ana5_pan:   ['/Mixer/pan', 0, 4], 
     203            self.mix1ana6_pan:   ['/Mixer/pan', 0, 5], 
     204            self.mix1ana7_pan:   ['/Mixer/pan', 0, 6], 
     205            self.mix1ana8_pan:   ['/Mixer/pan', 0, 7], 
     206            self.mix1aes1_pan:   ['/Mixer/pan', 0, 8], 
     207            self.mix1aes2_pan:   ['/Mixer/pan', 0, 9], 
     208            self.mix1spdif1_pan: ['/Mixer/pan', 0, 10], 
     209            self.mix1spdif2_pan: ['/Mixer/pan', 0, 11], 
     210            self.mix1adat1_pan:  ['/Mixer/pan', 0, 12], 
     211            self.mix1adat2_pan:  ['/Mixer/pan', 0, 13], 
     212            self.mix1adat3_pan:  ['/Mixer/pan', 0, 14], 
     213            self.mix1adat4_pan:  ['/Mixer/pan', 0, 15], 
     214            self.mix1adat5_pan:  ['/Mixer/pan', 0, 16], 
     215            self.mix1adat6_pan:  ['/Mixer/pan', 0, 17], 
     216            self.mix1adat7_pan:  ['/Mixer/pan', 0, 18], 
     217            self.mix1adat8_pan:  ['/Mixer/pan', 0, 19], 
     218 
     219            self.mix2ana1_pan:   ['/Mixer/pan', 1, 0], 
     220            self.mix2ana2_pan:   ['/Mixer/pan', 1, 1], 
     221            self.mix2ana3_pan:   ['/Mixer/pan', 1, 2], 
     222            self.mix2ana4_pan:   ['/Mixer/pan', 1, 3], 
     223            self.mix2ana5_pan:   ['/Mixer/pan', 1, 4], 
     224            self.mix2ana6_pan:   ['/Mixer/pan', 1, 5], 
     225            self.mix2ana7_pan:   ['/Mixer/pan', 1, 6], 
     226            self.mix2ana8_pan:   ['/Mixer/pan', 1, 7], 
     227            self.mix2aes1_pan:   ['/Mixer/pan', 1, 8], 
     228            self.mix2aes2_pan:   ['/Mixer/pan', 1, 9], 
     229            self.mix2spdif1_pan: ['/Mixer/pan', 1, 10], 
     230            self.mix2spdif2_pan: ['/Mixer/pan', 1, 11], 
     231            self.mix2adat1_pan:  ['/Mixer/pan', 1, 12], 
     232            self.mix2adat2_pan:  ['/Mixer/pan', 1, 13], 
     233            self.mix2adat3_pan:  ['/Mixer/pan', 1, 14], 
     234            self.mix2adat4_pan:  ['/Mixer/pan', 1, 15], 
     235            self.mix2adat5_pan:  ['/Mixer/pan', 1, 16], 
     236            self.mix2adat6_pan:  ['/Mixer/pan', 1, 17], 
     237            self.mix2adat7_pan:  ['/Mixer/pan', 1, 18], 
     238            self.mix2adat8_pan:  ['/Mixer/pan', 1, 19], 
     239 
     240            self.mix3ana1_pan:   ['/Mixer/pan', 2, 0], 
     241            self.mix3ana2_pan:   ['/Mixer/pan', 2, 1], 
     242            self.mix3ana3_pan:   ['/Mixer/pan', 2, 2], 
     243            self.mix3ana4_pan:   ['/Mixer/pan', 2, 3], 
     244            self.mix3ana5_pan:   ['/Mixer/pan', 2, 4], 
     245            self.mix3ana6_pan:   ['/Mixer/pan', 2, 5], 
     246            self.mix3ana7_pan:   ['/Mixer/pan', 2, 6], 
     247            self.mix3ana8_pan:   ['/Mixer/pan', 2, 7], 
     248            self.mix3aes1_pan:   ['/Mixer/pan', 2, 8], 
     249            self.mix3aes2_pan:   ['/Mixer/pan', 2, 9], 
     250            self.mix3spdif1_pan: ['/Mixer/pan', 2, 10], 
     251            self.mix3spdif2_pan: ['/Mixer/pan', 2, 11], 
     252            self.mix3adat1_pan:  ['/Mixer/pan', 2, 12], 
     253            self.mix3adat2_pan:  ['/Mixer/pan', 2, 13], 
     254            self.mix3adat3_pan:  ['/Mixer/pan', 2, 14], 
     255            self.mix3adat4_pan:  ['/Mixer/pan', 2, 15], 
     256            self.mix3adat5_pan:  ['/Mixer/pan', 2, 16], 
     257            self.mix3adat6_pan:  ['/Mixer/pan', 2, 17], 
     258            self.mix3adat7_pan:  ['/Mixer/pan', 2, 18], 
     259            self.mix3adat8_pan:  ['/Mixer/pan', 2, 19], 
     260 
     261            self.mix4ana1_pan:   ['/Mixer/pan', 3, 0], 
     262            self.mix4ana2_pan:   ['/Mixer/pan', 3, 1], 
     263            self.mix4ana3_pan:   ['/Mixer/pan', 3, 2], 
     264            self.mix4ana4_pan:   ['/Mixer/pan', 3, 3], 
     265            self.mix4ana5_pan:   ['/Mixer/pan', 3, 4], 
     266            self.mix4ana6_pan:   ['/Mixer/pan', 3, 5], 
     267            self.mix4ana7_pan:   ['/Mixer/pan', 3, 6], 
     268            self.mix4ana8_pan:   ['/Mixer/pan', 3, 7], 
     269            self.mix4aes1_pan:   ['/Mixer/pan', 3, 8], 
     270            self.mix4aes2_pan:   ['/Mixer/pan', 3, 9], 
     271            self.mix4spdif1_pan: ['/Mixer/pan', 3, 10], 
     272            self.mix4spdif2_pan: ['/Mixer/pan', 3, 11], 
     273            self.mix4adat1_pan:  ['/Mixer/pan', 3, 12], 
     274            self.mix4adat2_pan:  ['/Mixer/pan', 3, 13], 
     275            self.mix4adat3_pan:  ['/Mixer/pan', 3, 14], 
     276            self.mix4adat4_pan:  ['/Mixer/pan', 3, 15], 
     277            self.mix4adat5_pan:  ['/Mixer/pan', 3, 16], 
     278            self.mix4adat6_pan:  ['/Mixer/pan', 3, 17], 
     279            self.mix4adat7_pan:  ['/Mixer/pan', 3, 18], 
     280            self.mix4adat8_pan:  ['/Mixer/pan', 3, 19], 
     281        } 
    161282 
    162283        self.Controls={ 
    163             self.mix1ana1_pan:   ['/Mixer/Mix1/Ana1_pan'], 
    164             self.mix1ana2_pan:   ['/Mixer/Mix1/Ana2_pan'], 
    165             self.mix1ana3_pan:   ['/Mixer/Mix1/Ana3_pan'], 
    166             self.mix1ana4_pan:   ['/Mixer/Mix1/Ana4_pan'], 
    167             self.mix1ana5_pan:   ['/Mixer/Mix1/Ana5_pan'], 
    168             self.mix1ana6_pan:   ['/Mixer/Mix1/Ana6_pan'], 
    169             self.mix1ana7_pan:   ['/Mixer/Mix1/Ana7_pan'], 
    170             self.mix1ana8_pan:   ['/Mixer/Mix1/Ana8_pan'], 
    171             self.mix1adat1_pan:  ['/Mixer/Mix1/Adat1_pan'], 
    172             self.mix1adat2_pan:  ['/Mixer/Mix1/Adat2_pan'], 
    173             self.mix1adat3_pan:  ['/Mixer/Mix1/Adat3_pan'], 
    174             self.mix1adat4_pan:  ['/Mixer/Mix1/Adat4_pan'], 
    175             self.mix1adat5_pan:  ['/Mixer/Mix1/Adat5_pan'], 
    176             self.mix1adat6_pan:  ['/Mixer/Mix1/Adat6_pan'], 
    177             self.mix1adat7_pan:  ['/Mixer/Mix1/Adat7_pan'], 
    178             self.mix1adat8_pan:  ['/Mixer/Mix1/Adat8_pan'], 
    179             self.mix1aes1_pan:   ['/Mixer/Mix1/Aes1_pan'], 
    180             self.mix1aes2_pan:   ['/Mixer/Mix1/Aes2_pan'], 
    181             self.mix1spdif1_pan:  ['/Mixer/Mix1/Spdif1_pan'], 
    182             self.mix1spdif2_pan:  ['/Mixer/Mix1/Spdif2_pan'], 
    183  
    184             self.mix2ana1_pan:   ['/Mixer/Mix2/Ana1_pan'], 
    185             self.mix2ana2_pan:   ['/Mixer/Mix2/Ana2_pan'], 
    186             self.mix2ana3_pan:   ['/Mixer/Mix2/Ana3_pan'], 
    187             self.mix2ana4_pan:   ['/Mixer/Mix2/Ana4_pan'], 
    188             self.mix2ana5_pan:   ['/Mixer/Mix2/Ana5_pan'], 
    189             self.mix2ana6_pan:   ['/Mixer/Mix2/Ana6_pan'], 
    190             self.mix2ana7_pan:   ['/Mixer/Mix2/Ana7_pan'], 
    191             self.mix2ana8_pan:   ['/Mixer/Mix2/Ana8_pan'], 
    192             self.mix2adat1_pan:  ['/Mixer/Mix2/Adat1_pan'], 
    193             self.mix2adat2_pan:  ['/Mixer/Mix2/Adat2_pan'], 
    194             self.mix2adat3_pan:  ['/Mixer/Mix2/Adat3_pan'], 
    195             self.mix2adat4_pan:  ['/Mixer/Mix2/Adat4_pan'], 
    196             self.mix2adat5_pan:  ['/Mixer/Mix2/Adat5_pan'], 
    197             self.mix2adat6_pan:  ['/Mixer/Mix2/Adat6_pan'], 
    198             self.mix2adat7_pan:  ['/Mixer/Mix2/Adat7_pan'], 
    199             self.mix2adat8_pan:  ['/Mixer/Mix2/Adat8_pan'], 
    200             self.mix2aes1_pan:   ['/Mixer/Mix2/Aes1_pan'], 
    201             self.mix2aes2_pan:   ['/Mixer/Mix2/Aes2_pan'], 
    202             self.mix2spdif1_pan:  ['/Mixer/Mix2/Spdif1_pan'], 
    203             self.mix2spdif2_pan:  ['/Mixer/Mix2/Spdif2_pan'], 
    204  
    205             self.mix3ana1_pan:   ['/Mixer/Mix3/Ana1_pan'], 
    206             self.mix3ana2_pan:   ['/Mixer/Mix3/Ana2_pan'], 
    207             self.mix3ana3_pan:   ['/Mixer/Mix3/Ana3_pan'], 
    208             self.mix3ana4_pan:   ['/Mixer/Mix3/Ana4_pan'], 
    209             self.mix3ana5_pan:   ['/Mixer/Mix3/Ana5_pan'], 
    210             self.mix3ana6_pan:   ['/Mixer/Mix3/Ana6_pan'], 
    211             self.mix3ana7_pan:   ['/Mixer/Mix3/Ana7_pan'], 
    212             self.mix3ana8_pan:   ['/Mixer/Mix3/Ana8_pan'], 
    213             self.mix3adat1_pan:  ['/Mixer/Mix3/Adat1_pan'], 
    214             self.mix3adat2_pan:  ['/Mixer/Mix3/Adat2_pan'], 
    215             self.mix3adat3_pan:  ['/Mixer/Mix3/Adat3_pan'], 
    216             self.mix3adat4_pan:  ['/Mixer/Mix3/Adat4_pan'], 
    217             self.mix3adat5_pan:  ['/Mixer/Mix3/Adat5_pan'], 
    218             self.mix3adat6_pan:  ['/Mixer/Mix3/Adat6_pan'], 
    219             self.mix3adat7_pan:  ['/Mixer/Mix3/Adat7_pan'], 
    220             self.mix3adat8_pan:  ['/Mixer/Mix3/Adat8_pan'], 
    221             self.mix3aes1_pan:   ['/Mixer/Mix3/Aes1_pan'], 
    222             self.mix3aes2_pan:   ['/Mixer/Mix3/Aes2_pan'], 
    223             self.mix3spdif1_pan:  ['/Mixer/Mix3/Spdif1_pan'], 
    224             self.mix3spdif2_pan:  ['/Mixer/Mix3/Spdif2_pan'], 
    225  
    226             self.mix4ana1_pan:   ['/Mixer/Mix4/Ana1_pan'], 
    227             self.mix4ana2_pan:   ['/Mixer/Mix4/Ana2_pan'], 
    228             self.mix4ana3_pan:   ['/Mixer/Mix4/Ana3_pan'], 
    229             self.mix4ana4_pan:   ['/Mixer/Mix4/Ana4_pan'], 
    230             self.mix4ana5_pan:   ['/Mixer/Mix4/Ana5_pan'], 
    231             self.mix4ana6_pan:   ['/Mixer/Mix4/Ana6_pan'], 
    232             self.mix4ana7_pan:   ['/Mixer/Mix4/Ana7_pan'], 
    233             self.mix4ana8_pan:   ['/Mixer/Mix4/Ana8_pan'], 
    234             self.mix4adat1_pan:  ['/Mixer/Mix4/Adat1_pan'], 
    235             self.mix4adat2_pan:  ['/Mixer/Mix4/Adat2_pan'], 
    236             self.mix4adat3_pan:  ['/Mixer/Mix4/Adat3_pan'], 
    237             self.mix4adat4_pan:  ['/Mixer/Mix4/Adat4_pan'], 
    238             self.mix4adat5_pan:  ['/Mixer/Mix4/Adat5_pan'], 
    239             self.mix4adat6_pan:  ['/Mixer/Mix4/Adat6_pan'], 
    240             self.mix4adat7_pan:  ['/Mixer/Mix4/Adat7_pan'], 
    241             self.mix4adat8_pan:  ['/Mixer/Mix4/Adat8_pan'], 
    242             self.mix4aes1_pan:   ['/Mixer/Mix4/Aes1_pan'], 
    243             self.mix4aes2_pan:   ['/Mixer/Mix4/Aes2_pan'], 
    244             self.mix4spdif1_pan:  ['/Mixer/Mix4/Spdif1_pan'], 
    245             self.mix4spdif2_pan:  ['/Mixer/Mix4/Spdif2_pan'], 
    246  
    247284            self.ana1_trimgain:  ['/Mixer/Control/Ana1_trimgain'], 
    248285            self.ana2_trimgain:  ['/Mixer/Control/Ana2_trimgain'], 
     
    251288        } 
    252289 
     290        self.ChannelBinarySwitches={ 
     291            self.mix1ana1_mute:  ['/Mixer/mute', 0, 0], 
     292            self.mix1ana2_mute:  ['/Mixer/mute', 0, 1], 
     293            self.mix1ana3_mute:  ['/Mixer/mute', 0, 2], 
     294            self.mix1ana4_mute:  ['/Mixer/mute', 0, 3], 
     295            self.mix1ana5_mute:  ['/Mixer/mute', 0, 4], 
     296            self.mix1ana6_mute:  ['/Mixer/mute', 0, 5], 
     297            self.mix1ana7_mute:  ['/Mixer/mute', 0, 6], 
     298            self.mix1ana8_mute:  ['/Mixer/mute', 0, 7], 
     299            self.mix1aes1_mute:  ['/Mixer/mute', 0, 8], 
     300            self.mix1aes2_mute:  ['/Mixer/mute', 0, 9], 
     301            self.mix1spdif1_mute: ['/Mixer/mute', 0, 10], 
     302            self.mix1spdif2_mute: ['/Mixer/mute', 0, 11], 
     303            self.mix1adat1_mute: ['/Mixer/mute', 0, 12], 
     304            self.mix1adat2_mute: ['/Mixer/mute', 0, 13], 
     305            self.mix1adat3_mute: ['/Mixer/mute', 0, 14], 
     306            self.mix1adat4_mute: ['/Mixer/mute', 0, 15], 
     307            self.mix1adat5_mute: ['/Mixer/mute', 0, 16], 
     308            self.mix1adat6_mute: ['/Mixer/mute', 0, 17], 
     309            self.mix1adat7_mute: ['/Mixer/mute', 0, 18], 
     310            self.mix1adat8_mute: ['/Mixer/mute', 0, 19], 
     311            self.mix1ana1_solo:  ['/Mixer/solo', 0, 0], 
     312            self.mix1ana2_solo:  ['/Mixer/solo', 0, 1], 
     313            self.mix1ana3_solo:  ['/Mixer/solo', 0, 2], 
     314            self.mix1ana4_solo:  ['/Mixer/solo', 0, 3], 
     315            self.mix1ana5_solo:  ['/Mixer/solo', 0, 4], 
     316            self.mix1ana6_solo:  ['/Mixer/solo', 0, 5], 
     317            self.mix1ana7_solo:  ['/Mixer/solo', 0, 6], 
     318            self.mix1ana8_solo:  ['/Mixer/solo', 0, 7], 
     319            self.mix1aes1_solo:  ['/Mixer/solo', 0, 8], 
     320            self.mix1aes2_solo:  ['/Mixer/solo', 0, 9], 
     321            self.mix1spdif1_solo: ['/Mixer/solo', 0, 10], 
     322            self.mix1spdif2_solo: ['/Mixer/solo', 0, 11], 
     323            self.mix1adat1_solo: ['/Mixer/solo', 0, 12], 
     324            self.mix1adat2_solo: ['/Mixer/solo', 0, 13], 
     325            self.mix1adat3_solo: ['/Mixer/solo', 0, 14], 
     326            self.mix1adat4_solo: ['/Mixer/solo', 0, 15], 
     327            self.mix1adat5_solo: ['/Mixer/solo', 0, 16], 
     328            self.mix1adat6_solo: ['/Mixer/solo', 0, 17], 
     329            self.mix1adat7_solo: ['/Mixer/solo', 0, 18], 
     330            self.mix1adat8_solo: ['/Mixer/solo', 0, 19], 
     331 
     332            self.mix2ana1_mute:  ['/Mixer/mute', 1, 0], 
     333            self.mix2ana2_mute:  ['/Mixer/mute', 1, 1], 
     334            self.mix2ana3_mute:  ['/Mixer/mute', 1, 2], 
     335            self.mix2ana4_mute:  ['/Mixer/mute', 1, 3], 
     336            self.mix2ana5_mute:  ['/Mixer/mute', 1, 4], 
     337            self.mix2ana6_mute:  ['/Mixer/mute', 1, 5], 
     338            self.mix2ana7_mute:  ['/Mixer/mute', 1, 6], 
     339            self.mix2ana8_mute:  ['/Mixer/mute', 1, 7], 
     340            self.mix2aes1_mute:  ['/Mixer/mute', 1, 8], 
     341            self.mix2aes2_mute:  ['/Mixer/mute', 1, 9], 
     342            self.mix2spdif1_mute: ['/Mixer/mute', 1, 10], 
     343            self.mix2spdif2_mute: ['/Mixer/mute', 1, 11], 
     344            self.mix2adat1_mute: ['/Mixer/mute', 1, 12], 
     345            self.mix2adat2_mute: ['/Mixer/mute', 1, 13], 
     346            self.mix2adat3_mute: ['/Mixer/mute', 1, 14], 
     347            self.mix2adat4_mute: ['/Mixer/mute', 1, 15], 
     348            self.mix2adat5_mute: ['/Mixer/mute', 1, 16], 
     349            self.mix2adat6_mute: ['/Mixer/mute', 1, 17], 
     350            self.mix2adat7_mute: ['/Mixer/mute', 1, 18], 
     351            self.mix2adat8_mute: ['/Mixer/mute', 1, 19], 
     352            self.mix2ana1_solo:  ['/Mixer/solo', 1, 0], 
     353            self.mix2ana2_solo:  ['/Mixer/solo', 1, 1], 
     354            self.mix2ana3_solo:  ['/Mixer/solo', 1, 2], 
     355            self.mix2ana4_solo:  ['/Mixer/solo', 1, 3], 
     356            self.mix2ana5_solo:  ['/Mixer/solo', 1, 4], 
     357            self.mix2ana6_solo:  ['/Mixer/solo', 1, 5], 
     358            self.mix2ana7_solo:  ['/Mixer/solo', 1, 6], 
     359            self.mix2ana8_solo:  ['/Mixer/solo', 1, 7], 
     360            self.mix2aes1_solo:  ['/Mixer/solo', 1, 8], 
     361            self.mix2aes2_solo:  ['/Mixer/solo', 1, 9], 
     362            self.mix2spdif1_solo: ['/Mixer/solo', 1, 10], 
     363            self.mix2spdif2_solo: ['/Mixer/solo', 1, 11], 
     364            self.mix2adat1_solo: ['/Mixer/solo', 1, 12], 
     365            self.mix2adat2_solo: ['/Mixer/solo', 1, 13], 
     366            self.mix2adat3_solo: ['/Mixer/solo', 1, 14], 
     367            self.mix2adat4_solo: ['/Mixer/solo', 1, 15], 
     368            self.mix2adat5_solo: ['/Mixer/solo', 1, 16], 
     369            self.mix2adat6_solo: ['/Mixer/solo', 1, 17], 
     370            self.mix2adat7_solo: ['/Mixer/solo', 1, 18], 
     371            self.mix2adat8_solo: ['/Mixer/solo', 1, 19], 
     372 
     373            self.mix3ana1_mute:  ['/Mixer/mute', 2, 0], 
     374            self.mix3ana2_mute:  ['/Mixer/mute', 2, 1], 
     375            self.mix3ana3_mute:  ['/Mixer/mute', 2, 2], 
     376            self.mix3ana4_mute:  ['/Mixer/mute', 2, 3], 
     377            self.mix3ana5_mute:  ['/Mixer/mute', 2, 4], 
     378            self.mix3ana6_mute:  ['/Mixer/mute', 2, 5], 
     379            self.mix3ana7_mute:  ['/Mixer/mute', 2, 6], 
     380            self.mix3ana8_mute:  ['/Mixer/mute', 2, 7], 
     381            self.mix3aes1_mute:  ['/Mixer/mute', 2, 8], 
     382            self.mix3aes2_mute:  ['/Mixer/mute', 2, 9], 
     383            self.mix3spdif1_mute: ['/Mixer/mute', 2, 10], 
     384            self.mix3spdif2_mute: ['/Mixer/mute', 2, 11], 
     385            self.mix3adat1_mute: ['/Mixer/mute', 2, 12], 
     386            self.mix3adat2_mute: ['/Mixer/mute', 2, 13], 
     387            self.mix3adat3_mute: ['/Mixer/mute', 2, 14], 
     388            self.mix3adat4_mute: ['/Mixer/mute', 2, 15], 
     389            self.mix3adat5_mute: ['/Mixer/mute', 2, 16], 
     390            self.mix3adat6_mute: ['/Mixer/mute', 2, 17], 
     391            self.mix3adat7_mute: ['/Mixer/mute', 2, 18], 
     392            self.mix3adat8_mute: ['/Mixer/mute', 2, 19], 
     393            self.mix3ana1_solo:  ['/Mixer/solo', 2, 0], 
     394            self.mix3ana2_solo:  ['/Mixer/solo', 2, 1], 
     395            self.mix3ana3_solo:  ['/Mixer/solo', 2, 2], 
     396            self.mix3ana4_solo:  ['/Mixer/solo', 2, 3], 
     397            self.mix3ana5_solo:  ['/Mixer/solo', 2, 4], 
     398            self.mix3ana6_solo:  ['/Mixer/solo', 2, 5], 
     399            self.mix3ana7_solo:  ['/Mixer/solo', 2, 6], 
     400            self.mix3ana8_solo:  ['/Mixer/solo', 2, 7], 
     401            self.mix3aes1_solo:  ['/Mixer/solo', 2, 8], 
     402            self.mix3aes2_solo:  ['/Mixer/solo', 2, 9], 
     403            self.mix3spdif1_solo: ['/Mixer/solo', 2, 10], 
     404            self.mix3spdif2_solo: ['/Mixer/solo', 2, 11], 
     405            self.mix3adat1_solo: ['/Mixer/solo', 2, 12], 
     406            self.mix3adat2_solo: ['/Mixer/solo', 2, 13], 
     407            self.mix3adat3_solo: ['/Mixer/solo', 2, 14], 
     408            self.mix3adat4_solo: ['/Mixer/solo', 2, 15], 
     409            self.mix3adat5_solo: ['/Mixer/solo', 2, 16], 
     410            self.mix3adat6_solo: ['/Mixer/solo', 2, 17], 
     411            self.mix3adat7_solo: ['/Mixer/solo', 2, 18], 
     412            self.mix3adat8_solo: ['/Mixer/solo', 2, 19], 
     413 
     414            self.mix4ana1_mute:  ['/Mixer/mute', 3, 0], 
     415            self.mix4ana2_mute:  ['/Mixer/mute', 3, 1], 
     416            self.mix4ana3_mute:  ['/Mixer/mute', 3, 2], 
     417            self.mix4ana4_mute:  ['/Mixer/mute', 3, 3], 
     418            self.mix4ana5_mute:  ['/Mixer/mute', 3, 4], 
     419            self.mix4ana6_mute:  ['/Mixer/mute', 3, 5], 
     420            self.mix4ana7_mute:  ['/Mixer/mute', 3, 6], 
     421            self.mix4ana8_mute:  ['/Mixer/mute', 3, 7], 
     422            self.mix4aes1_mute:  ['/Mixer/mute', 3, 8], 
     423            self.mix4aes2_mute:  ['/Mixer/mute', 3, 9], 
     424            self.mix4spdif1_mute: ['/Mixer/mute', 3, 10], 
     425            self.mix4spdif2_mute: ['/Mixer/mute', 3, 11], 
     426            self.mix4adat1_mute: ['/Mixer/mute', 3, 12], 
     427            self.mix4adat2_mute: ['/Mixer/mute', 3, 13], 
     428            self.mix4adat3_mute: ['/Mixer/mute', 3, 14], 
     429            self.mix4adat4_mute: ['/Mixer/mute', 3, 15], 
     430            self.mix4adat5_mute: ['/Mixer/mute', 3, 16], 
     431            self.mix4adat6_mute: ['/Mixer/mute', 3, 17], 
     432            self.mix4adat7_mute: ['/Mixer/mute', 3, 18], 
     433            self.mix4adat8_mute: ['/Mixer/mute', 3, 19], 
     434            self.mix4ana1_solo:  ['/Mixer/solo', 3, 0], 
     435            self.mix4ana2_solo:  ['/Mixer/solo', 3, 1], 
     436            self.mix4ana3_solo:  ['/Mixer/solo', 3, 2], 
     437            self.mix4ana4_solo:  ['/Mixer/solo', 3, 3], 
     438            self.mix4ana5_solo:  ['/Mixer/solo', 3, 4], 
     439            self.mix4ana6_solo:  ['/Mixer/solo', 3, 5], 
     440            self.mix4ana7_solo:  ['/Mixer/solo', 3, 6], 
     441            self.mix4ana8_solo:  ['/Mixer/solo', 3, 7], 
     442            self.mix4aes1_solo:  ['/Mixer/solo', 3, 8], 
     443            self.mix4aes2_solo:  ['/Mixer/solo', 3, 9], 
     444            self.mix4spdif1_solo: ['/Mixer/solo', 3, 10], 
     445            self.mix4spdif2_solo: ['/Mixer/solo', 3, 11], 
     446            self.mix4adat1_solo: ['/Mixer/solo', 3, 12], 
     447            self.mix4adat2_solo: ['/Mixer/solo', 3, 13], 
     448            self.mix4adat3_solo: ['/Mixer/solo', 3, 14], 
     449            self.mix4adat4_solo: ['/Mixer/solo', 3, 15], 
     450            self.mix4adat5_solo: ['/Mixer/solo', 3, 16], 
     451            self.mix4adat6_solo: ['/Mixer/solo', 3, 17], 
     452            self.mix4adat7_solo: ['/Mixer/solo', 3, 18], 
     453            self.mix4adat8_solo: ['/Mixer/solo', 3, 19], 
     454        } 
     455 
    253456        self.BinarySwitches={ 
    254             self.mix1ana1_mute:  ['/Mixer/Mix1/Ana1_mute'], 
    255             self.mix1ana2_mute:  ['/Mixer/Mix1/Ana2_mute'], 
    256             self.mix1ana3_mute:  ['/Mixer/Mix1/Ana3_mute'], 
    257             self.mix1ana4_mute:  ['/Mixer/Mix1/Ana4_mute'], 
    258             self.mix1ana5_mute:  ['/Mixer/Mix1/Ana5_mute'], 
    259             self.mix1ana6_mute:  ['/Mixer/Mix1/Ana6_mute'], 
    260             self.mix1ana7_mute:  ['/Mixer/Mix1/Ana7_mute'], 
    261             self.mix1ana8_mute:  ['/Mixer/Mix1/Ana8_mute'], 
    262             self.mix1ana1_solo:  ['/Mixer/Mix1/Ana1_solo'], 
    263             self.mix1ana2_solo:  ['/Mixer/Mix1/Ana2_solo'], 
    264             self.mix1ana3_solo:  ['/Mixer/Mix1/Ana3_solo'], 
    265             self.mix1ana4_solo:  ['/Mixer/Mix1/Ana4_solo'], 
    266             self.mix1ana5_solo:  ['/Mixer/Mix1/Ana5_solo'], 
    267             self.mix1ana6_solo:  ['/Mixer/Mix1/Ana6_solo'], 
    268             self.mix1ana7_solo:  ['/Mixer/Mix1/Ana7_solo'], 
    269             self.mix1ana8_solo:  ['/Mixer/Mix1/Ana8_solo'], 
    270             self.mix1adat1_mute: ['/Mixer/Mix1/Adat1_mute'], 
    271             self.mix1adat2_mute: ['/Mixer/Mix1/Adat2_mute'], 
    272             self.mix1adat3_mute: ['/Mixer/Mix1/Adat3_mute'], 
    273             self.mix1adat4_mute: ['/Mixer/Mix1/Adat4_mute'], 
    274             self.mix1adat5_mute: ['/Mixer/Mix1/Adat5_mute'], 
    275             self.mix1adat6_mute: ['/Mixer/Mix1/Adat6_mute'], 
    276             self.mix1adat7_mute: ['/Mixer/Mix1/Adat7_mute'], 
    277             self.mix1adat8_mute: ['/Mixer/Mix1/Adat8_mute'], 
    278             self.mix1adat1_solo: ['/Mixer/Mix1/Adat1_solo'], 
    279             self.mix1adat2_solo: ['/Mixer/Mix1/Adat2_solo'], 
    280             self.mix1adat3_solo: ['/Mixer/Mix1/Adat3_solo'], 
    281             self.mix1adat4_solo: ['/Mixer/Mix1/Adat4_solo'], 
    282             self.mix1adat5_solo: ['/Mixer/Mix1/Adat5_solo'], 
    283             self.mix1adat6_solo: ['/Mixer/Mix1/Adat6_solo'], 
    284             self.mix1adat7_solo: ['/Mixer/Mix1/Adat7_solo'], 
    285             self.mix1adat8_solo: ['/Mixer/Mix1/Adat8_solo'], 
    286             self.mix1aes1_mute:  ['/Mixer/Mix1/Aes1_mute'], 
    287             self.mix1aes2_mute:  ['/Mixer/Mix1/Aes2_mute'], 
    288             self.mix1aes1_solo:  ['/Mixer/Mix1/Aes1_solo'], 
    289             self.mix1aes2_solo:  ['/Mixer/Mix1/Aes2_solo'], 
    290             self.mix1spdif1_mute: ['/Mixer/Mix1/Spdif1_mute'], 
    291             self.mix1spdif2_mute: ['/Mixer/Mix1/Spdif2_mute'], 
    292             self.mix1spdif1_solo: ['/Mixer/Mix1/Spdif1_solo'], 
    293             self.mix1spdif2_solo: ['/Mixer/Mix1/Spdif2_solo'], 
    294457            self.mix1_mute:      ['/Mixer/Mix1/Mix_mute'], 
    295  
    296             self.mix2ana1_mute:  ['/Mixer/Mix2/Ana1_mute'], 
    297             self.mix2ana2_mute:  ['/Mixer/Mix2/Ana2_mute'], 
    298             self.mix2ana3_mute:  ['/Mixer/Mix2/Ana3_mute'], 
    299             self.mix2ana4_mute:  ['/Mixer/Mix2/Ana4_mute'], 
    300             self.mix2ana5_mute:  ['/Mixer/Mix2/Ana5_mute'], 
    301             self.mix2ana6_mute:  ['/Mixer/Mix2/Ana6_mute'], 
    302             self.mix2ana7_mute:  ['/Mixer/Mix2/Ana7_mute'], 
    303             self.mix2ana8_mute:  ['/Mixer/Mix2/Ana8_mute'], 
    304             self.mix2ana1_solo:  ['/Mixer/Mix2/Ana1_solo'], 
    305             self.mix2ana2_solo:  ['/Mixer/Mix2/Ana2_solo'], 
    306             self.mix2ana3_solo:  ['/Mixer/Mix2/Ana3_solo'], 
    307             self.mix2ana4_solo:  ['/Mixer/Mix2/Ana4_solo'], 
    308             self.mix2ana5_solo:  ['/Mixer/Mix2/Ana5_solo'], 
    309             self.mix2ana6_solo:  ['/Mixer/Mix2/Ana6_solo'], 
    310             self.mix2ana7_solo:  ['/Mixer/Mix2/Ana7_solo'], 
    311             self.mix2ana8_solo:  ['/Mixer/Mix2/Ana8_solo'], 
    312             self.mix2adat1_mute: ['/Mixer/Mix2/Adat1_mute'], 
    313             self.mix2adat2_mute: ['/Mixer/Mix2/Adat2_mute'], 
    314             self.mix2adat3_mute: ['/Mixer/Mix2/Adat3_mute'], 
    315             self.mix2adat4_mute: ['/Mixer/Mix2/Adat4_mute'], 
    316             self.mix2adat5_mute: ['/Mixer/Mix2/Adat5_mute'], 
    317             self.mix2adat6_mute: ['/Mixer/Mix2/Adat6_mute'], 
    318             self.mix2adat7_mute: ['/Mixer/Mix2/Adat7_mute'], 
    319             self.mix2adat8_mute: ['/Mixer/Mix2/Adat8_mute'], 
    320             self.mix2adat1_solo: ['/Mixer/Mix2/Adat1_solo'], 
    321             self.mix2adat2_solo: ['/Mixer/Mix2/Adat2_solo'], 
    322             self.mix2adat3_solo: ['/Mixer/Mix2/Adat3_solo'], 
    323             self.mix2adat4_solo: ['/Mixer/Mix2/Adat4_solo'], 
    324             self.mix2adat5_solo: ['/Mixer/Mix2/Adat5_solo'], 
    325             self.mix2adat6_solo: ['/Mixer/Mix2/Adat6_solo'], 
    326             self.mix2adat7_solo: ['/Mixer/Mix2/Adat7_solo'], 
    327             self.mix2adat8_solo: ['/Mixer/Mix2/Adat8_solo'], 
    328             self.mix2aes1_mute:  ['/Mixer/Mix2/Aes1_mute'], 
    329             self.mix2aes2_mute:  ['/Mixer/Mix2/Aes2_mute'], 
    330             self.mix2aes1_solo:  ['/Mixer/Mix2/Aes1_solo'], 
    331             self.mix2aes2_solo:  ['/Mixer/Mix2/Aes2_solo'], 
    332             self.mix2spdif1_mute: ['/Mixer/Mix2/Spdif1_mute'], 
    333             self.mix2spdif2_mute: ['/Mixer/Mix2/Spdif2_mute'], 
    334             self.mix2spdif1_solo: ['/Mixer/Mix2/Spdif1_solo'], 
    335             self.mix2spdif2_solo: ['/Mixer/Mix2/Spdif2_solo'], 
    336458            self.mix2_mute:      ['/Mixer/Mix2/Mix_mute'], 
    337  
    338             self.mix3ana1_mute:  ['/Mixer/Mix3/Ana1_mute'], 
    339             self.mix3ana2_mute:  ['/Mixer/Mix3/Ana2_mute'], 
    340             self.mix3ana3_mute:  ['/Mixer/Mix3/Ana3_mute'], 
    341             self.mix3ana4_mute:  ['/Mixer/Mix3/Ana4_mute'], 
    342             self.mix3ana5_mute:  ['/Mixer/Mix3/Ana5_mute'], 
    343             self.mix3ana6_mute:  ['/Mixer/Mix3/Ana6_mute'], 
    344             self.mix3ana7_mute:  ['/Mixer/Mix3/Ana7_mute'], 
    345             self.mix3ana8_mute:  ['/Mixer/Mix3/Ana8_mute'], 
    346             self.mix3ana1_solo:  ['/Mixer/Mix3/Ana1_solo'], 
    347             self.mix3ana2_solo:  ['/Mixer/Mix3/Ana2_solo'], 
    348             self.mix3ana3_solo:  ['/Mixer/Mix3/Ana3_solo'], 
    349             self.mix3ana4_solo:  ['/Mixer/Mix3/Ana4_solo'], 
    350             self.mix3ana5_solo:  ['/Mixer/Mix3/Ana5_solo'], 
    351             self.mix3ana6_solo:  ['/Mixer/Mix3/Ana6_solo'], 
    352             self.mix3ana7_solo:  ['/Mixer/Mix3/Ana7_solo'], 
    353             self.mix3ana8_solo:  ['/Mixer/Mix3/Ana8_solo'], 
    354             self.mix3adat1_mute: ['/Mixer/Mix3/Adat1_mute'], 
    355             self.mix3adat2_mute: ['/Mixer/Mix3/Adat2_mute'], 
    356             self.mix3adat3_mute: ['/Mixer/Mix3/Adat3_mute'], 
    357             self.mix3adat4_mute: ['/Mixer/Mix3/Adat4_mute'], 
    358             self.mix3adat5_mute: ['/Mixer/Mix3/Adat5_mute'], 
    359             self.mix3adat6_mute: ['/Mixer/Mix3/Adat6_mute'], 
    360             self.mix3adat7_mute: ['/Mixer/Mix3/Adat7_mute'], 
    361             self.mix3adat8_mute: ['/Mixer/Mix3/Adat8_mute'], 
    362             self.mix3adat1_solo: ['/Mixer/Mix3/Adat1_solo'], 
    363             self.mix3adat2_solo: ['/Mixer/Mix3/Adat2_solo'], 
    364             self.mix3adat3_solo: ['/Mixer/Mix3/Adat3_solo'], 
    365             self.mix3adat4_solo: ['/Mixer/Mix3/Adat4_solo'], 
    366             self.mix3adat5_solo: ['/Mixer/Mix3/Adat5_solo'], 
    367             self.mix3adat6_solo: ['/Mixer/Mix3/Adat6_solo'], 
    368             self.mix3adat7_solo: ['/Mixer/Mix3/Adat7_solo'], 
    369             self.mix3adat8_solo: ['/Mixer/Mix3/Adat8_solo'], 
    370             self.mix3aes1_mute:  ['/Mixer/Mix3/Aes1_mute'], 
    371             self.mix3aes2_mute:  ['/Mixer/Mix3/Aes2_mute'], 
    372             self.mix3aes1_solo:  ['/Mixer/Mix3/Aes1_solo'], 
    373             self.mix3aes2_solo:  ['/Mixer/Mix3/Aes2_solo'], 
    374             self.mix3spdif1_mute: ['/Mixer/Mix3/Spdif1_mute'], 
    375             self.mix3spdif2_mute: ['/Mixer/Mix3/Spdif2_mute'], 
    376             self.mix3spdif1_solo: ['/Mixer/Mix3/Spdif1_solo'], 
    377             self.mix3spdif2_solo: ['/Mixer/Mix3/Spdif2_solo'], 
    378459            self.mix3_mute:      ['/Mixer/Mix3/Mix_mute'], 
    379  
    380             self.mix4ana1_mute:  ['/Mixer/Mix4/Ana1_mute'], 
    381             self.mix4ana2_mute:  ['/Mixer/Mix4/Ana2_mute'], 
    382             self.mix4ana3_mute:  ['/Mixer/Mix4/Ana3_mute'], 
    383             self.mix4ana4_mute:  ['/Mixer/Mix4/Ana4_mute'], 
    384             self.mix4ana5_mute:  ['/Mixer/Mix4/Ana5_mute'], 
    385             self.mix4ana6_mute:  ['/Mixer/Mix4/Ana6_mute'], 
    386             self.mix4ana7_mute:  ['/Mixer/Mix4/Ana7_mute'], 
    387             self.mix4ana8_mute:  ['/Mixer/Mix4/Ana8_mute'], 
    388             self.mix4ana1_solo:  ['/Mixer/Mix4/Ana1_solo'], 
    389             self.mix4ana2_solo:  ['/Mixer/Mix4/Ana2_solo'], 
    390             self.mix4ana3_solo:  ['/Mixer/Mix4/Ana3_solo'], 
    391             self.mix4ana4_solo:  ['/Mixer/Mix4/Ana4_solo'], 
    392             self.mix4ana5_solo:  ['/Mixer/Mix4/Ana5_solo'], 
    393             self.mix4ana6_solo:  ['/Mixer/Mix4/Ana6_solo'], 
    394             self.mix4ana7_solo:  ['/Mixer/Mix4/Ana7_solo'], 
    395             self.mix4ana8_solo:  ['/Mixer/Mix4/Ana8_solo'], 
    396             self.mix4adat1_mute: ['/Mixer/Mix4/Adat1_mute'], 
    397             self.mix4adat2_mute: ['/Mixer/Mix4/Adat2_mute'], 
    398             self.mix4adat3_mute: ['/Mixer/Mix4/Adat3_mute'], 
    399             self.mix4adat4_mute: ['/Mixer/Mix4/Adat4_mute'], 
    400             self.mix4adat5_mute: ['/Mixer/Mix4/Adat5_mute'], 
    401             self.mix4adat6_mute: ['/Mixer/Mix4/Adat6_mute'], 
    402             self.mix4adat7_mute: ['/Mixer/Mix4/Adat7_mute'], 
    403             self.mix4adat8_mute: ['/Mixer/Mix4/Adat8_mute'], 
    404             self.mix4adat1_solo: ['/Mixer/Mix4/Adat1_solo'], 
    405             self.mix4adat2_solo: ['/Mixer/Mix4/Adat2_solo'], 
    406             self.mix4adat3_solo: ['/Mixer/Mix4/Adat3_solo'], 
    407             self.mix4adat4_solo: ['/Mixer/Mix4/Adat4_solo'], 
    408             self.mix4adat5_solo: ['/Mixer/Mix4/Adat5_solo'], 
    409             self.mix4adat6_solo: ['/Mixer/Mix4/Adat6_solo'], 
    410             self.mix4adat7_solo: ['/Mixer/Mix4/Adat7_solo'], 
    411             self.mix4adat8_solo: ['/Mixer/Mix4/Adat8_solo'], 
    412             self.mix4aes1_mute:  ['/Mixer/Mix4/Aes1_mute'], 
    413             self.mix4aes2_mute:  ['/Mixer/Mix4/Aes2_mute'], 
    414             self.mix4aes1_solo:  ['/Mixer/Mix4/Aes1_solo'], 
    415             self.mix4aes2_solo:  ['/Mixer/Mix4/Aes2_solo'], 
    416             self.mix4spdif1_mute: ['/Mixer/Mix4/Spdif1_mute'], 
    417             self.mix4spdif2_mute: ['/Mixer/Mix4/Spdif2_mute'], 
    418             self.mix4spdif1_solo: ['/Mixer/Mix4/Spdif1_solo'], 
    419             self.mix4spdif2_solo: ['/Mixer/Mix4/Spdif2_solo'], 
    420460            self.mix4_mute:      ['/Mixer/Mix4/Mix_mute'], 
    421461 
     
    436476        # Ultimately these may be rolled into the BinarySwitches controls, 
    437477        # but since they aren't implemented and therefore need to be 
    438         # disabled it's easier to keep them separate for the moment. 
     478        # disabled it's easier to keep them separate for the moment.  The 
     479        # dbus path for these is yet to be finalised too - for example we 
     480        # may end up using a matrix mixer. 
    439481        self.PairSwitches={ 
    440482            self.mix1ana1_2_pair:   ['Mixer/Mix1/Ana1_2_pair'], 
     
    525567            # has both. 
    526568            self.mix1_aes_group.setTitle("Mic inputs") 
     569            self.mix2_aes_group.setTitle("Mic inputs") 
     570            self.mix3_aes_group.setTitle("Mic inputs") 
     571            self.mix4_aes_group.setTitle("Mic inputs") 
    527572            # FIXME: when implmented, will mic channels just reuse the AES/EBU 
    528573            # dbus path?  If not we'll have to reset the respective values in 
     
    531576            if (not(self.has_aesebu_inputs)): 
    532577                self.mix1_aes_group.setEnabled(False) 
     578                self.mix2_aes_group.setEnabled(False) 
     579                self.mix3_aes_group.setEnabled(False) 
     580                self.mix4_aes_group.setEnabled(False) 
    533581        if (not(self.has_spdif_inputs)): 
    534582            self.mix1_spdif_group.setEnabled(False) 
     583            self.mix2_spdif_group.setEnabled(False) 
     584            self.mix3_spdif_group.setEnabled(False) 
     585            self.mix4_spdif_group.setEnabled(False) 
    535586 
    536587        # Some devices don't have the option of selecting an optical SPDIF 
     
    552603            self.mix1_aes_group.setEnabled(False) 
    553604            self.mix1_spdif_group.setEnabled(False) 
     605            self.mix2_adat_group.setEnabled(False) 
     606            self.mix2_aes_group.setEnabled(False) 
     607            self.mix2_spdif_group.setEnabled(False) 
     608            self.mix3_adat_group.setEnabled(False) 
     609            self.mix3_aes_group.setEnabled(False) 
     610            self.mix3_spdif_group.setEnabled(False) 
     611            self.mix4_adat_group.setEnabled(False) 
     612            self.mix4_aes_group.setEnabled(False) 
     613            self.mix4_spdif_group.setEnabled(False) 
    554614        if (self.sample_rate > 48000): 
    555615            print "Disabling controls not present above 48 kHz" 
    556616            self.mix1_adat58_group.setEnabled(False) 
     617            self.mix2_adat58_group.setEnabled(False) 
     618            self.mix3_adat58_group.setEnabled(False) 
     619            self.mix4_adat58_group.setEnabled(False) 
    557620 
    558621        # Now fetch the current values into the respective controls.  Don't 
     
    561624            if (not(ctrl.isEnabled())): 
    562625                continue 
     626            vol = 128-self.hw.getMatrixMixerValue(info[0], info[1], info[2]) 
     627            print "%s for mix %d channel %d is %d" % (info[0], info[1], info[2], vol) 
     628            ctrl.setValue(vol) 
     629            QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateChannelFader) 
     630 
     631        for ctrl, info in self.Faders.iteritems(): 
     632            if (not(ctrl.isEnabled())): 
     633                continue 
    563634            vol = 128-self.hw.getDiscrete(info[0]) 
    564             print "%s channel fader is %d" % (info[0] , vol) 
     635            print "%s mix fader is %d" % (info[0] , vol) 
    565636            ctrl.setValue(vol) 
    566637            QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateFader) 
     638 
     639        for ctrl, info in self.ChannelControls.iteritems(): 
     640            if (not(ctrl.isEnabled())): 
     641                continue 
     642            pan = self.hw.getMatrixMixerValue(info[0], info[1], info[2]) 
     643            print "%s for mix %d channel %d is %d" % (info[0], info[1], info[2], pan) 
     644            ctrl.setValue(pan) 
     645            QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateChannelControl) 
    567646 
    568647        for ctrl, info in self.Controls.iteritems(): 
     
    579658            ctrl.setEnabled(False) 
    580659 
     660        for ctrl, info in self.ChannelBinarySwitches.iteritems(): 
     661            if (not(ctrl.isEnabled())): 
     662                continue 
     663            val = self.hw.getMatrixMixerValue(info[0], info[1], info[2]) 
     664            print "%s for mix %d channel %d is %d" % (info[0] , info[1], info[2], val) 
     665            ctrl.setChecked(val) 
     666            QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateChannelBinarySwitch) 
     667 
    581668        for ctrl, info in self.BinarySwitches.iteritems(): 
    582669            if (not(ctrl.isEnabled())):