Le vendredi 20 janvier 2012 à 08:25 +1030, Jonathan Woithe a écrit :
On Thu, Jan 19, 2012 at 11:00:06AM +0100, Adrian Knoth wrote:
>
> > > according to the convention that inputs will be columns and outputs
> > > will
> > > be rows as represented in faddo-mixer matrix-mixer.
> > > 
> > > Maybe Jonathan who use a RME device may tell us what matrix-mixer
> > > looks
> > > like to in his case ?
> > 
> > For RME, when the matrix mixer is used to mix inputs to outputs[1], I
> > chose
> > to have rows represent outputs and columns represent inputs.  This
> > mirrors
> > what audio people are used to on monitor desks
>
> I guess that's true, mixing consoles usually have the input vertically.

Indeed.

> > and (I think) the arrangement used in RME's totalmix application under
> > other OSes.
>
> This, unfortunately, is not true. TotalMix (RME's mixing tool) uses rows
> for sources and columns for sinks.

Whatever.  To be honest I haven't really used TotalMix beyond that which was
necessary to confirm some on-the-wire protocol details.  At this point I
still think that having inputs as columns will make more sense to most audio
people so that's what I'll keep using for the RME.  I should note that for
the RME mixer I clearly label the columns/row as "input" and "output"
respectively, so it should be clear to the user which is which regardless of
their previous experiences or personal preference.

Regards
  jonathan

I sent my last email without yet reading part of the discussion (a wrong configuration of my ffado-devel-list subscription I corrected further), especially an answer of Clemens. Having a look to the different functions he mentioned is convincing: there is truly an implicit "left-to-top" (row<=>inputs, columns<=>outputs) rule in ffado which, if I well understood him, is probably useless at the level we discuss (speaking in terms of inputs/outputs would be sufficient and not confusing), but which exists. "Discarding" this rule would probably be a lot of work and a source of future dysfunction for both developers and users, wouldn't it ?

So probably it would be better to follow the rule; I mistook in my last email. Since the mixer matrix would never be directly addressed except by the functions of class MatrixMixer, there is no need to "transpose" it (I was misled by having the habit of addressing directly matrices for large linear system solutions).
Then the graphic displaying of the matrix coefficients like in ffado-mixer is just matter of convenience and representing rows as columns and vice-versa probably does not require much modifications. And possibly, offering the possibility of transposing the view at the user convenience would overcome the problem (I understand this is additional work ...).

So I modified again in the sense mentioned by Clemens: with further candidate patch, mixer matrix will display outputs as columns and inputs as rows as displayed by ffado-mixer.
Of course, this is just a "candidate": its final form depends on the choice you, the developers, would like to adopt. And probably of various comments and recommendations you would like to provide.

Regards,

Phil

Index: src/dice/focusrite/saffire_pro40.cpp
===================================================================
--- src/dice/focusrite/saffire_pro40.cpp (révision 2019)
+++ src/dice/focusrite/saffire_pro40.cpp (copie de travail)
@@ -24,7 +24,21 @@
#include "saffire_pro40.h"

#include "focusrite_eap.h"
-
+//
+// Under 48kHz Saffire pro 40 has
+//  - 8 analogic inputs (mic/line)
+//  - 8 ADAT inputs
+//  - 2 SPDIF inputs
+//  - 20 ieee1394 inputs
+//
+//  - 18 mixer inputs
+//
+//  - 16 mixer outputs
+//  - 10 analogic outputs
+//  - 8 ADAT outputs
+//  - 2 SPDIF outputs
+//  - 20 ieee1394 outputs
+//
namespace Dice {
namespace Focusrite {

@@ -44,20 +58,23 @@
}

void SaffirePro40::SaffirePro40EAP::setupSources() {
-    addSource("SPDIF",  6,  2, eRS_AES);
+    addSource("SPDIF",  0,  2, eRS_AES);
     addSource("ADAT",   0,  8, eRS_ADAT);
-    addSource("Analog", 0,  8, eRS_InS0);
+    addSource("Analog", 16,  8, eRS_InS0);
     addSource("Mixer",  0, 16, eRS_Mixer);
-    addSource("1394",   0, 16, eRS_ARX0);
+    addSource("1394",   0, 10, eRS_ARX0);
+    addSource("1394",   0, 10, eRS_ARX1, 10);
     addSource("Mute",   0,  1, eRS_Muted);
}
void SaffirePro40::SaffirePro40EAP::setupDestinations() {
-    addDestination("SPDIF",  6,  2, eRD_AES);
+    addDestination("SPDIF",  0,  2, eRD_AES);
     addDestination("ADAT",   0,  8, eRD_ADAT);
-    addDestination("Analog", 0,  8, eRD_InS0);
+    addDestination("Analog", 0,  2, eRD_InS0);
+    addDestination("Analog", 0,  8, eRD_InS1, 2);
     addDestination("Mixer",  0, 16, eRD_Mixer0);
     addDestination("Mixer",  0,  2, eRD_Mixer1, 16);
-    addDestination("1394",   0, 16, eRD_ATX0);
+    addDestination("1394",   0, 10, eRD_ATX0);
+    addDestination("1394",   0, 10, eRD_ATX1, 10);
     addDestination("Mute",   0,  1, eRD_Muted);
}

Index: src/dice/dice_eap.cpp
===================================================================
--- src/dice/dice_eap.cpp (révision 2019)
+++ src/dice/dice_eap.cpp (copie de travail)
@@ -793,7 +793,12 @@
     return true;
}

-// ----------- Mixer -------------
+// -------------------------------- Mixer ----------------------------------
+//   Dice matrix-mixer is a one-dimensional array with inputs index varying
+//    first
+//
+//   "ffado convention" is that inputs are rows and outputs are columns
+//
EAP::Mixer::Mixer(EAP &p)
: Control::MatrixMixer(&p.m_device, "MatrixMixer")
, m_eap(p)
@@ -973,6 +978,10 @@
     char tmp[bufflen];
     int cnt;

+    //
+    // Caution the user that, displaying as further, because inputs index varies first
+    //  inputs will appears as columns at the opposite of the "ffado convention"
+    printMessage("   -- inputs index -->>\n");
     cnt = 0;
     for(int j=0; j < nb_inputs; j++) {
         cnt += snprintf(tmp+cnt, bufflen-cnt, "   %02d   ", j);
@@ -1032,7 +1041,7 @@
         return false;
     }
     int nb_inputs = m_eap.m_mixer_nb_tx;
-    int addr = ((nb_inputs * row) + col) * 4;
+    int addr = ((nb_inputs * col) + row) * 4;
     quadlet_t tmp = (quadlet_t) val;
     if(!m_eap.writeRegBlock(eRT_Mixer, 4+addr, &tmp, 4)) {
         debugError("Failed to write coefficient\n");
@@ -1045,7 +1054,7 @@
EAP::Mixer::getValue( const int row, const int col)
{
     int nb_inputs = m_eap.m_mixer_nb_tx;
-    int addr = ((nb_inputs * row) + col) * 4;
+    int addr = ((nb_inputs * col) + row) * 4;
     quadlet_t tmp;
     if(!m_eap.readRegBlock(eRT_Mixer, 4+addr, &tmp, 4)) {
         debugError("Failed to read coefficient\n");