alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards
@ 2011-04-04 12:34 Adrian Knoth
  2011-04-04 12:34 ` [PATCH 1/4] hdspmixer: Add a 9th pseudo preset Adrian Knoth
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Adrian Knoth @ 2011-04-04 12:34 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

Hi!


This series of patches was developed for EMAtech. They discovered that
when running with multiple cards, switching between cards would lose all
current changes made to the last active card.

Obviously, this is undesired behaviour. Though rather small, it nearly
took me 6hrs to get this right, and it could still be improved, but I
like to take hdspmixer into a completely different direction:

I want to remove the card switching code completely and simply run a
single instance per card, that is, if you have more than one card,
you'll say something like hdspmixer -c 1 (or even a card name).

Likewise, the preset files should then only contain the settings for a
single card. Right now, it stores everything for three cards, and if you
have four, then you'd be left in the rain. Also, when the order of cards
changes, the mixer settings would end up on the wrong card.

Long story short: the current approach is a dead-end.


Cheers

Adrian Knoth (4):
  hdspmixer: Add a 9th pseudo preset
  hdspmixer: Save preset before switching cards
  hdspmixer: Recall 1st preset on all cards, not just on the first
  hdspmixer: Initialize headphones out in presets

 hdspmixer/src/HDSPMixerCard.cxx         |    1 +
 hdspmixer/src/HDSPMixerCard.h           |    2 +
 hdspmixer/src/HDSPMixerCardSelector.cxx |    2 +
 hdspmixer/src/HDSPMixerIOMixer.cxx      |    2 +-
 hdspmixer/src/HDSPMixerIOMixer.h        |    2 +-
 hdspmixer/src/HDSPMixerOutput.cxx       |    4 +-
 hdspmixer/src/HDSPMixerOutput.h         |    2 +-
 hdspmixer/src/HDSPMixerWindow.cxx       |   48 ++++++++++++++++++++++++++++--
 hdspmixer/src/HDSPMixerWindow.h         |    4 ++-
 hdspmixer/src/defines.h                 |    6 ++++
 10 files changed, 63 insertions(+), 10 deletions(-)

-- 
1.7.4.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] hdspmixer: Add a 9th pseudo preset
  2011-04-04 12:34 [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Adrian Knoth
@ 2011-04-04 12:34 ` Adrian Knoth
  2011-04-04 12:34 ` [PATCH 2/4] hdspmixer: Save preset before switching cards Adrian Knoth
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Adrian Knoth @ 2011-04-04 12:34 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

When switching cards, all current settings are lost. To have a place
where to store them, let's add a virtual 9th preset which can be used as
a temporary scratch pad.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
---
 hdspmixer/src/HDSPMixerIOMixer.cxx |    2 +-
 hdspmixer/src/HDSPMixerIOMixer.h   |    2 +-
 hdspmixer/src/HDSPMixerOutput.cxx  |    4 ++--
 hdspmixer/src/HDSPMixerOutput.h    |    2 +-
 hdspmixer/src/HDSPMixerWindow.cxx  |    2 +-
 hdspmixer/src/HDSPMixerWindow.h    |    2 +-
 hdspmixer/src/defines.h            |    6 ++++++
 7 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/hdspmixer/src/HDSPMixerIOMixer.cxx b/hdspmixer/src/HDSPMixerIOMixer.cxx
index 987be41..9283d64 100644
--- a/hdspmixer/src/HDSPMixerIOMixer.cxx
+++ b/hdspmixer/src/HDSPMixerIOMixer.cxx
@@ -38,7 +38,7 @@ HDSPMixerIOMixer::HDSPMixerIOMixer(int x, int y, int w, int h, int ch, int type)
 	p_iomixer_xpm = iomixer_r_xpm;
     }
     for (int j = 0; j < MAX_CARDS; ++j) {
-	for (int i = 0; i < 8; ++i) {
+	for (int i = 0; i < NUM_PRESETS; ++i) {
 	    data[j][0][i] = new HDSPMixerStripData();
 	    data[j][1][i] = new HDSPMixerStripData();
 	    data[j][2][i] = new HDSPMixerStripData();
diff --git a/hdspmixer/src/HDSPMixerIOMixer.h b/hdspmixer/src/HDSPMixerIOMixer.h
index 2ec7f05..aa12487 100644
--- a/hdspmixer/src/HDSPMixerIOMixer.h
+++ b/hdspmixer/src/HDSPMixerIOMixer.h
@@ -56,7 +56,7 @@ private:
 	std::stringstream channel_name;
     void update_child(Fl_Widget &widget);
 public:
-    HDSPMixerStripData *data[MAX_CARDS][3][8]; /* data[card][mode(ss/ds/qs)][preset number] */
+    HDSPMixerStripData *data[MAX_CARDS][3][NUM_PRESETS]; /* data[card][mode(ss/ds/qs)][preset number] */
     HDSPMixerPan *pan;
     HDSPMixerFader *fader;
     HDSPMixerPeak *peak;
diff --git a/hdspmixer/src/HDSPMixerOutput.cxx b/hdspmixer/src/HDSPMixerOutput.cxx
index 5047825..f5981b0 100644
--- a/hdspmixer/src/HDSPMixerOutput.cxx
+++ b/hdspmixer/src/HDSPMixerOutput.cxx
@@ -170,8 +170,8 @@ static char const *labels_9632_qs[8] = {
 HDSPMixerOutput::HDSPMixerOutput(int x, int y, int w, int h, int num):Fl_Group(x, y, w, h)
 {
 
-    for (int j = 0; j < 3; ++j) {
-	for (int i = 0; i < 8; ++i) {
+    for (int j = 0; j < MAX_CARDS; ++j) {
+	for (int i = 0; i < NUM_PRESETS; ++i) {
 	    data[j][0][i] = new HDSPMixerOutputData();
 	    data[j][1][i] = new HDSPMixerOutputData();
 	    data[j][2][i] = new HDSPMixerOutputData();
diff --git a/hdspmixer/src/HDSPMixerOutput.h b/hdspmixer/src/HDSPMixerOutput.h
index 2bc3d5c..6278cfd 100644
--- a/hdspmixer/src/HDSPMixerOutput.h
+++ b/hdspmixer/src/HDSPMixerOutput.h
@@ -52,7 +52,7 @@ private:
     HDSPMixerWindow *basew;    
     void update_child(Fl_Widget& widget);
 public:
-    HDSPMixerOutputData *data[MAX_CARDS][3][8]; /* data[card][mode(ss/ds/qs)][preset number] */
+    HDSPMixerOutputData *data[MAX_CARDS][3][NUM_PRESETS]; /* data[card][mode(ss/ds/qs)][preset number] */
     HDSPMixerFader *fader;
     HDSPMixerGain *gain;
     HDSPMixerMeter *meter;
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx
index 960ec0f..a327904 100644
--- a/hdspmixer/src/HDSPMixerWindow.cxx
+++ b/hdspmixer/src/HDSPMixerWindow.cxx
@@ -791,7 +791,7 @@ HDSPMixerWindow::HDSPMixerWindow(int x, int y, int w, int h, const char *label,
 	}	
     }
     for (int j = 0; j < MAX_CARDS; j++) {
-	for (int i = 0; i < 8; ++i) {
+	for (int i = 0; i < NUM_PRESETS; ++i) {
 	    data[j][0][i] = new HDSPMixerPresetData();
 	    data[j][1][i] = new HDSPMixerPresetData();
 	    data[j][2][i] = new HDSPMixerPresetData();
diff --git a/hdspmixer/src/HDSPMixerWindow.h b/hdspmixer/src/HDSPMixerWindow.h
index dfc7d59..0c2674f 100644
--- a/hdspmixer/src/HDSPMixerWindow.h
+++ b/hdspmixer/src/HDSPMixerWindow.h
@@ -73,7 +73,7 @@ public:
     Fl_Scroll *scroll;
     HDSPMixerSetup *setup;
     HDSPMixerAbout *about;
-    HDSPMixerPresetData *data[MAX_CARDS][3][8]; /* data[card number][mode(ss/ds/qs)][preset number] */
+    HDSPMixerPresetData *data[MAX_CARDS][3][NUM_PRESETS]; /* data[card number][mode(ss/ds/qs)][preset number] */
     HDSPMixerCard *cards[MAX_CARDS];
     HDSPMixerInputs *inputs;
     HDSPMixerPlaybacks *playbacks;
diff --git a/hdspmixer/src/defines.h b/hdspmixer/src/defines.h
index d29c37c..af5c382 100644
--- a/hdspmixer/src/defines.h
+++ b/hdspmixer/src/defines.h
@@ -49,6 +49,12 @@
 
 #define MAX_CARDS	3
 
+/* Number of presets. 8 presets visible to the user, the 9th is used for
+ * holding temporary mixer data when switching cards, so it's not a real
+ * preset but more like a scratch pad.
+ */
+#define NUM_PRESETS	9
+
 typedef unsigned long long int int64;
 
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] hdspmixer: Save preset before switching cards
  2011-04-04 12:34 [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Adrian Knoth
  2011-04-04 12:34 ` [PATCH 1/4] hdspmixer: Add a 9th pseudo preset Adrian Knoth
@ 2011-04-04 12:34 ` Adrian Knoth
  2011-04-04 12:34 ` [PATCH 3/4] hdspmixer: Recall 1st preset on all cards, not just on the first Adrian Knoth
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Adrian Knoth @ 2011-04-04 12:34 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

When running with more than one card, switching cards would lose any
changes made to the current card. To avoid this inconvenience, save the
current settings to the virtual 9th preset and restore them when
switching back.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
---
 hdspmixer/src/HDSPMixerCard.cxx         |    1 +
 hdspmixer/src/HDSPMixerCard.h           |    2 +
 hdspmixer/src/HDSPMixerCardSelector.cxx |    2 +
 hdspmixer/src/HDSPMixerWindow.cxx       |   41 ++++++++++++++++++++++++++++++-
 hdspmixer/src/HDSPMixerWindow.h         |    2 +
 5 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/hdspmixer/src/HDSPMixerCard.cxx b/hdspmixer/src/HDSPMixerCard.cxx
index f3205b9..fbd5de5 100644
--- a/hdspmixer/src/HDSPMixerCard.cxx
+++ b/hdspmixer/src/HDSPMixerCard.cxx
@@ -186,6 +186,7 @@ HDSPMixerCard::HDSPMixerCard(int cardtype, int id, char *shortname)
     
     /* Set channels and mappings */
     adjustSettings();
+    last_preset = last_dirty = 0;
         
     basew = NULL;
 }
diff --git a/hdspmixer/src/HDSPMixerCard.h b/hdspmixer/src/HDSPMixerCard.h
index 032c61f..d2ef8a6 100644
--- a/hdspmixer/src/HDSPMixerCard.h
+++ b/hdspmixer/src/HDSPMixerCard.h
@@ -48,6 +48,8 @@ public:
     int channels_input, channels_playback, window_width, window_height, card_id;
     int channels_output;
     int type;
+    int last_preset; /* Last activated preset before switching to another card */
+    int last_dirty; /* Last dirty flag before switching to another card */
     char *channel_map_input, *channel_map_playback;
     char *dest_map;
     char *meter_map_input, *meter_map_playback;
diff --git a/hdspmixer/src/HDSPMixerCardSelector.cxx b/hdspmixer/src/HDSPMixerCardSelector.cxx
index d83c4c9..d685009 100644
--- a/hdspmixer/src/HDSPMixerCardSelector.cxx
+++ b/hdspmixer/src/HDSPMixerCardSelector.cxx
@@ -48,9 +48,11 @@ void HDSPMixerCardSelector::draw()
 void HDSPMixerCardSelector::ActivateCard (int i)
 {
   card = i + 1;
+  basew->stashPreset(); /* save current mixer state */
   basew->current_card = i;
   basew->cards[i]->setMode (basew->cards[i]->getSpeed ());
   basew->setTitleWithFilename();
+  basew->unstashPreset(); /* restore previous mixer state */
   redraw ();
 }
 
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx
index a327904..7848190 100644
--- a/hdspmixer/src/HDSPMixerWindow.cxx
+++ b/hdspmixer/src/HDSPMixerWindow.cxx
@@ -609,7 +609,44 @@ void HDSPMixerWindow::setTitleWithFilename(void)
     setTitle(filename);
 }
 
+void HDSPMixerWindow::stashPreset(void)
+{
+    cards[current_card]->last_preset = current_preset;
+    cards[current_card]->last_dirty = dirty;
+    /* save the current mixer state to the virtual 9th preset */
+    inputs->buttons->presets->save_preset(9);
+}
 
+void HDSPMixerWindow::unstashPreset(void)
+{
+    /* load temporary data from virtual 9th preset */
+    inputs->buttons->presets->restore_preset(9);
+    
+    current_preset = cards[current_card]->last_preset;
+    /* Internal notion of playback in use. Relevant for blinking buttons */
+    inputs->buttons->presets->preset = current_preset + 1;
+    dirty = cards[current_card]->last_dirty;
+    /* Preset masks (which preset button is green) */
+    inputs->buttons->presets->presetmask = (int)pow(2, current_preset);
+    if (dirty) {
+        /* make the buttons blink if it's unsaved. We need to remove any
+         * existing triggers to dirty_cb, because dirty_cb is called
+         * every 0.3 seconds and enabling/disabling (highlight/unlight) the
+         * buttons, so if we have too many callbacks, the buttons would
+         * remain in one state --> no blinking. We need exactly one.
+         */
+        Fl::remove_timeout(dirty_cb, (void *)this);
+        Fl::add_timeout(0.3, dirty_cb, (void *)this);
+    } else {
+        /* Hack. I don't know why this is necessary, but if we're clean,
+         * we need to recall the preset again to correctly reflect
+         * the dirty/undirty state.
+         *
+         * Though it's a little bit redundant, it at least won't do any harm.
+         */
+        inputs->buttons->presets->preset_change(current_preset+1);
+    }
+}
 
 void HDSPMixerWindow::restoreDefaults(int card)
 {
@@ -848,8 +885,10 @@ HDSPMixerWindow::HDSPMixerWindow(int x, int y, int w, int h, const char *label,
     Fl::add_handler(handler_cb);
     Fl::add_timeout(0.030, readregisters_cb, this);
     i = 0;
-    while (i < MAX_CARDS && cards[i] != NULL)
+    while (i < MAX_CARDS && cards[i] != NULL) {
+      current_card = i;
       inputs->buttons->cardselector->ActivateCard (i++);
+    }
 }
 
 int HDSPMixerWindow::handle(int e) 
diff --git a/hdspmixer/src/HDSPMixerWindow.h b/hdspmixer/src/HDSPMixerWindow.h
index 0c2674f..134db3e 100644
--- a/hdspmixer/src/HDSPMixerWindow.h
+++ b/hdspmixer/src/HDSPMixerWindow.h
@@ -95,6 +95,8 @@ public:
     void load();
     void setTitle(std::string suffix);
     void setTitleWithFilename();
+    void stashPreset();
+    void unstashPreset();
 };
 
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] hdspmixer: Recall 1st preset on all cards, not just on the first
  2011-04-04 12:34 [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Adrian Knoth
  2011-04-04 12:34 ` [PATCH 1/4] hdspmixer: Add a 9th pseudo preset Adrian Knoth
  2011-04-04 12:34 ` [PATCH 2/4] hdspmixer: Save preset before switching cards Adrian Knoth
@ 2011-04-04 12:34 ` Adrian Knoth
  2011-04-04 12:34 ` [PATCH 4/4] hdspmixer: Initialize headphones out in presets Adrian Knoth
  2011-04-06  6:28 ` [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Adrian Knoth @ 2011-04-04 12:34 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

With the new "store current settings to the virtual 9th preset" before
switching cards code, one needs to make sure the actual mixer state is
loaded with sane values, either from the preset file or a generic
builtin preset.

Calling preset_change(1) is sufficient, setting all the required data.
However, in case of more than one RME card in the system, one needs to
call this function for each card, otherwise, some of the cards store
uninitialized data to the 9th preset, resulting in a weird mixer state
afterwards.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
---
 hdspmixer/src/HDSPMixerWindow.cxx |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx
index 7848190..5a7dac0 100644
--- a/hdspmixer/src/HDSPMixerWindow.cxx
+++ b/hdspmixer/src/HDSPMixerWindow.cxx
@@ -877,9 +877,10 @@ HDSPMixerWindow::HDSPMixerWindow(int x, int y, int w, int h, const char *label,
 	printf("Initializing default presets\n");
 	i = 0;
 	while (i < MAX_CARDS && cards[i] != NULL) {
+	    current_card = i;
 	    restoreDefaults(i++);
+	    inputs->buttons->presets->preset_change(1);
 	}
-	inputs->buttons->presets->preset_change(1);
     }
     Fl::atclose = atclose_cb;
     Fl::add_handler(handler_cb);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] hdspmixer: Initialize headphones out in presets
  2011-04-04 12:34 [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Adrian Knoth
                   ` (2 preceding siblings ...)
  2011-04-04 12:34 ` [PATCH 3/4] hdspmixer: Recall 1st preset on all cards, not just on the first Adrian Knoth
@ 2011-04-04 12:34 ` Adrian Knoth
  2011-04-06  6:28 ` [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Adrian Knoth @ 2011-04-04 12:34 UTC (permalink / raw)
  To: patch; +Cc: Adrian Knoth, alsa-devel

Cards like the multiface/digiface have additional headphones out. Those
were not initialized in the presets due to wrong loop boundaries:
maxdest represents the amount of physical stereo pairs, and chnls is
either equal or less, so the output fader array needs more iterations
than the playback section.

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
---
 hdspmixer/src/HDSPMixerWindow.cxx |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx
index 5a7dac0..75fbc4f 100644
--- a/hdspmixer/src/HDSPMixerWindow.cxx
+++ b/hdspmixer/src/HDSPMixerWindow.cxx
@@ -734,7 +734,7 @@ void HDSPMixerWindow::restoreDefaults(int card)
 
     for (int preset = 0; preset < 8; ++preset) {
 	for (int speed = 0; speed < num_modes; ++speed) {
-	    for (int i = 0; i < chnls[speed]; i+=2) {
+	    for (int i = 0; i < 2*maxdest[speed]; i+=2) {
     		for (int z = 0; z < maxdest[speed]; ++z) {
 		    /* Gain setup */
 		    if (cards[card]->type == H9632) {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards
  2011-04-04 12:34 [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Adrian Knoth
                   ` (3 preceding siblings ...)
  2011-04-04 12:34 ` [PATCH 4/4] hdspmixer: Initialize headphones out in presets Adrian Knoth
@ 2011-04-06  6:28 ` Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2011-04-06  6:28 UTC (permalink / raw)
  To: Adrian Knoth; +Cc: alsa-devel

At Mon,  4 Apr 2011 14:34:26 +0200,
Adrian Knoth wrote:
> 
> Hi!
> 
> 
> This series of patches was developed for EMAtech. They discovered that
> when running with multiple cards, switching between cards would lose all
> current changes made to the last active card.
> 
> Obviously, this is undesired behaviour. Though rather small, it nearly
> took me 6hrs to get this right, and it could still be improved, but I
> like to take hdspmixer into a completely different direction:
> 
> I want to remove the card switching code completely and simply run a
> single instance per card, that is, if you have more than one card,
> you'll say something like hdspmixer -c 1 (or even a card name).
> 
> Likewise, the preset files should then only contain the settings for a
> single card. Right now, it stores everything for three cards, and if you
> have four, then you'd be left in the rain. Also, when the order of cards
> changes, the mixer settings would end up on the wrong card.

But if you have single setup files, the card-order issue still
applies, no?

Though, I understand that a file-per-card is far easier to handle.

> Long story short: the current approach is a dead-end.

Go ahead!

Anyway, I applied your patches now.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-04-06  6:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-04 12:34 [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Adrian Knoth
2011-04-04 12:34 ` [PATCH 1/4] hdspmixer: Add a 9th pseudo preset Adrian Knoth
2011-04-04 12:34 ` [PATCH 2/4] hdspmixer: Save preset before switching cards Adrian Knoth
2011-04-04 12:34 ` [PATCH 3/4] hdspmixer: Recall 1st preset on all cards, not just on the first Adrian Knoth
2011-04-04 12:34 ` [PATCH 4/4] hdspmixer: Initialize headphones out in presets Adrian Knoth
2011-04-06  6:28 ` [PATCH 0/4] hdspmixer: rescue current mixer settings when switching cards Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).