At Fri, 9 Mar 2012 18:06:17 +0800,
Adam Lee wrote:
> 
> On Fri, Mar 09, 2012 at 10:30:27AM +0100, Takashi Iwai wrote:
> > At Fri, 9 Mar 2012 17:07:17 +0800,
> > Adam Lee wrote:
> > > 
> > > On Fri, Mar 09, 2012 at 07:40:27AM +0100, Takashi Iwai wrote:
> > > > At Fri, 9 Mar 2012 12:22:47 +0800,
> > > > Adam Lee wrote:
> > > > > 
> > > > > Add Vincent in cc, because conky read amixer's result.
> > > > > 
> > > > > On Thu, Mar 08, 2012 at 05:45:14PM +0100, Takashi Iwai wrote:
> > > > > > > * Adam Lee <adam8...@gmail.com> [2012-03-08 20:36 +0800]:
> > > > > > > 
> > > > > > > Package: alsa-utils
> > > > > > > Version: 1.0.25-1
> > > > > > > Severity: important
> > > > > > > 
> > > > > > > 
> > > > > > > db is not linear, but amixer believe it is.
> > > > > > > 
> > > > > > > "amixer get Master" says "Limits: Playback 0 - 74", then 
> > > > > > > everytime I run
> > > > > > > "amixer -q sset Master 10%-", there is 8db dec.
> > > > > > > 
> > > > > > > For example, at first Master is 100% and 0db, both alsamixer and 
> > > > > > > amixer
> > > > > > > think it is, and after I run "amixer -q sset Master 10%-", both
> > > > > > > alsamixer and amixer says Master is -8.00db, but alsamixer says 
> > > > > > > it is
> > > > > > > 72%, amixer says it is 89%.
> > > > > > > 
> > > > > > > alsamixer is right, amixer calc and set wrongly.
> > > > > > 
> > > > > > No, both are correct.  You are dreaming too much on the world 
> > > > > > unified
> > > > > > percentage representation :)
> > > > > > 
> > > > > > The percentage in amixer has nothing to do with dB level.
> > > > > > It's just the percentage of the raw value range of that mixer
> > > > > > element.  Thus showing 89% is correct.  It's 10% down from 100%
> > > > > > (1% is because of the resolution of the raw values).
> > > > > > 
> > > > > > Now, alsamixer shows the percentage in a different way.  It's
> > > > > > explained well in the source code (alsamixer/volume_mapping.c), but
> > > > > > not mentioned in the man page, unfortunately.
> > > > > > 
> > > > > >  * The mapping is designed so that the position in the interval is 
> > > > > > proportional
> > > > > >  * to the volume as a human ear would perceive it (i.e., the 
> > > > > > position is the
> > > > > >  * cubic root of the linear sample multiplication factor).  For 
> > > > > > controls with
> > > > > >  * a small range (24 dB or less), the mapping is linear in the dB 
> > > > > > values so
> > > > > >  * that each step has the same size visually.  Only for controls 
> > > > > > without dB
> > > > > >  * information, a linear mapping of the hardware volume register 
> > > > > > values is used
> > > > > >  * (this is the same algorithm as used in the old alsamixer).
> > > > > > 
> > > > > > The percentage representation in alsamixer corresponds to this
> > > > > > mapping, thus it's neither dB nor linear percent.
> > > > > > 
> > > > > 
> > > > > Hi, Takashi
> > > > > 
> > > > > Thank you for replying. But I still insist this is a bug. Three
> > > > > questions:
> > > > > 
> > > > > 1, several months ago, it's OK, both amixer and alsamixer use the 
> > > > > human
> > > > > mapping(0-10% and 90%-100% are the same change by a human ear), why 
> > > > > not
> > > > > now?
> > > > 
> > > > amixer hasn't been changed until yet.  It handles either in raw values
> > > > or in dB.  No human-ear mapping at all.  It's never changed since
> > > > years, and won't be changed.  If the volume mapping would be
> > > > implemented to amixer in future, it must be only optional.
> > > > 
> > > > Only the recent alsamixer introduced the volume mapping to visualize
> > > > the volumes reasonably.
> > > > 
> > > 
> > > OK, thank you. Maybe an optional will make everyone happy.
> > > 
> > > > > 2, conky(Vincent, I mean ${mixer}), some other software, lot of user's
> > > > > scripts use amixer to set or get volume, expecting the human mapping,
> > > > > why change the behavior?
> > > > 
> > > > You must be smoking something bad.  The behavior of amixer hasn't been
> > > > changed.
> > > > 
> > > 
> > > I figured out a reason probably, when the limits range is wide, like
> > > 0-65536, amixer's mapping and alsamixer's human-ear mapping are close.
> > > 
> > > If I remember right, my hardware's limits was 0-65536, but it becomes
> > > 0-74 after I run "alsactl init", but unfortunately, I don't know how to
> > > modify it back.
> > > 
> > > > > 3, alsamixer and amixer use the same dB value, why there is difference
> > > > > in percentage? If alsa-utils developer think the human mapping sucks,
> > > > > why you guys still use it in alsamixer? There is no "both correct", 
> > > > > the
> > > > > difference confuses user...
> > > > 
> > > > That's true.  alsamixer should have stopped showing the stupid
> > > > percentage.
> > > > 
> > > > The biggest understand is that people (including you) think there is
> > > > an absolutely perfect percentage definition for the sound level.  It's
> > > > an illusion.
> > > > 
> > > 
> > > I don't expect an absolutely perfect percentage definition. I want a
> > > human-ear mapping, which alsamixer does well, 100% is about as ten times
> > > loud as 10%.
> > 
> > How did you measure _quantitatively_ it's exactly ten times louder?
> > And you think 50% is ten times loud as 5% volume, 10% is ten times
> > loud as 1%?  Things aren't so easy, unfortunately.
> > 
> > > But amixer doesn't work like that, amixer's 100% is about
> > > as *one hundred times* as amixer's 10%.
> > 
> > Yes, this is what's amixer expected to behave.  It's a value just
> > representing the percentage of a "raw value" of the mixer element.
> > It never says it's corresponding to any practical volume.  This is the
> > misunderstanding first of all.
> > 
> > For example, I guess in your 64k case, the raw value is even not in dB
> > unit but it's a linear volume.  amixer doesn't care.  10% means only
> > the 6553 of 65536.  That's all.  So simple.
> > (In addition, amixer can handle dB, e.g. amixer set Master +10dB or
> >  such.  But it's not suitable for percentage unit because dB level
> >  can't be represented in the absolute percent volume -- what is 10% in
> >  dB?)
> > 
> > > Maybe it is beautiful, and alsamixer's human-ear mapping is stupid in
> > > the sound science universe. But as a common user, I don't think so. And
> > > I don't know how you guys put up with it :(
> > 
> > No, you misunderstand what I wrote.  alsamixer's mapping is really an
> > improvement.  That's why it was implemented recently.  But if it shows
> > a different number, user may wonder, just like you did.  If you didn't
> > see a number, you didn't notice the difference :)
> > 
> > But amixer wasn't changed.  amixer is a tool to manipulate raw
> > values.  Of course, it'd be also nice to implement the same percentage
> > expression, but as already mentioned, it should be activated only via
> > an option.  The default behavior of amixer must not be changed for
> > compatibility reason.
> > 
> 
> OK.
> 
> Looking forward to the option, if your time and other capacity allow :)

The implementation isn't too hard.  I wrote a quick patch now as below.
It became bigger than I thought since it contains many clean-ups that
are needed to adapt the mapped volume.

With the patch, amixer shows and reads the percent value with -M
option just like in alsamixer.


Takashi

---
diff --git a/amixer/Makefile.am b/amixer/Makefile.am
index fcd0e81..ba67a57 100644
--- a/amixer/Makefile.am
+++ b/amixer/Makefile.am
@@ -4,7 +4,7 @@ LDADD = -lm
 # CFLAGS += -g -Wall
 
 bin_PROGRAMS = amixer
-amixer_SOURCES = amixer.c
+amixer_SOURCES = amixer.c ../alsamixer/volume_mapping.c
 noinst_HEADERS = amixer.h
 man_MANS = amixer.1
 EXTRA_DIST = amixer.1
diff --git a/amixer/amixer.c b/amixer/amixer.c
index 9d2855d..a0a7387 100644
--- a/amixer/amixer.c
+++ b/amixer/amixer.c
@@ -29,7 +29,9 @@
 #include <assert.h>
 #include <alsa/asoundlib.h>
 #include <sys/poll.h>
+#include <stdint.h>
 #include "amixer.h"
+#include "../alsamixer/volume_mapping.h"
 
 #define LEVEL_BASIC            (1<<0)
 #define LEVEL_INACTIVE         (1<<1)
@@ -68,6 +70,8 @@ static int help(void)
        printf("  -i,--inactive   show also inactive controls\n");
        printf("  -a,--abstract L select abstraction level (none or basic)\n");
        printf("  -s,--stdin      Read and execute commands from stdin 
sequentially\n");
+       printf("  -R,--raw-volume Use the raw value (default)\n");
+       printf("  -M,--mapped-volume Use the mapped volume\n");
        printf("\nAvailable commands:\n");
        printf("  scontrols       show all mixer simple controls\n");
        printf("  scontents       show contents of all mixer simple controls 
(default command)\n");
@@ -187,9 +191,9 @@ static int convert_db_range(int val, int omin, int omax, 
int nmin, int nmax)
 
 /* Fuction to convert from volume to percentage. val = volume */
 
-static int convert_prange(int val, int min, int max)
+static int convert_prange(long val, long min, long max)
 {
-       int range = max - min;
+       long range = max - min;
        int tmp;
 
        if (range == 0)
@@ -204,29 +208,6 @@ static int convert_prange(int val, int min, int max)
 #define convert_prange1(val, min, max) \
        ceil((val) * ((max) - (min)) * 0.01 + (min))
 
-static const char *get_percent(int val, int min, int max)
-{
-       static char str[32];
-       int p;
-       
-       p = convert_prange(val, min, max);
-       sprintf(str, "%i [%i%%]", val, p);
-       return str;
-}
-
-#if 0
-static const char *get_percent1(int val, int min, int max, int min_dB, int 
max_dB)
-{
-       static char str[32];
-       int p, db;
-
-       p = convert_prange(val, min, max);
-       db = convert_db_range(val, min, max, min_dB, max_dB);
-       sprintf(str, "%i [%i%%] [%i.%02idB]", val, p, db / 100, abs(db % 100));
-       return str;
-}
-#endif
-
 static long get_integer(char **ptr, long min, long max)
 {
        long val = min;
@@ -288,26 +269,83 @@ struct volume_ops {
        int (*get)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c,
                   long *value);
        int (*set)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t c,
-                  long value);
+                  long value, int dir);
 };
        
-enum { VOL_RAW, VOL_DB };
+enum { VOL_RAW, VOL_DB, VOL_MAP };
 
 struct volume_ops_set {
        int (*has_volume)(snd_mixer_elem_t *elem);
-       struct volume_ops v[2];
+       struct volume_ops v[3];
 };
 
 static int set_playback_dB(snd_mixer_elem_t *elem,
-                          snd_mixer_selem_channel_id_t c, long value)
+                          snd_mixer_selem_channel_id_t c, long value, int dir)
 {
-       return snd_mixer_selem_set_playback_dB(elem, c, value, 0);
+       return snd_mixer_selem_set_playback_dB(elem, c, value, dir);
 }
 
 static int set_capture_dB(snd_mixer_elem_t *elem,
-                         snd_mixer_selem_channel_id_t c, long value)
+                         snd_mixer_selem_channel_id_t c, long value, int dir)
+{
+       return snd_mixer_selem_set_capture_dB(elem, c, value, dir);
+}
+
+static int set_playback_raw_volume(snd_mixer_elem_t *elem,
+                                  snd_mixer_selem_channel_id_t c,
+                                  long value, int dir)
+{
+       return snd_mixer_selem_set_playback_volume(elem, c, value);
+}
+
+static int set_capture_raw_volume(snd_mixer_elem_t *elem,
+                                 snd_mixer_selem_channel_id_t c,
+                                 long value, int dir)
+{
+       return snd_mixer_selem_set_capture_volume(elem, c, value);
+}
+
+/* FIXME: normalize to int32 space to be compatible with other types */
+#define MAP_VOL_RES    (INT32_MAX / 100)
+
+static int get_mapped_volume_range(snd_mixer_elem_t *elem,
+                                  long *pmin, long *pmax)
+{
+       *pmin = 0;
+       *pmax = MAP_VOL_RES;
+       return 0;
+}
+
+static int get_playback_mapped_volume(snd_mixer_elem_t *elem,
+                                     snd_mixer_selem_channel_id_t c,
+                                     long *value)
+{
+       *value = (rint)(get_normalized_playback_volume(elem, c) * MAP_VOL_RES);
+       return 0;
+}
+
+static int set_playback_mapped_volume(snd_mixer_elem_t *elem,
+                                     snd_mixer_selem_channel_id_t c,
+                                     long value, int dir)
 {
-       return snd_mixer_selem_set_capture_dB(elem, c, value, 0);
+       return set_normalized_playback_volume(elem, c,
+                                             (double)value / MAP_VOL_RES, dir);
+}
+
+static int get_capture_mapped_volume(snd_mixer_elem_t *elem,
+                                    snd_mixer_selem_channel_id_t c,
+                                    long *value)
+{
+       *value = (rint)(get_normalized_capture_volume(elem, c) * MAP_VOL_RES);
+       return 0;
+}
+
+static int set_capture_mapped_volume(snd_mixer_elem_t *elem,
+                                    snd_mixer_selem_channel_id_t c,
+                                    long value, int dir)
+{
+       return set_normalized_capture_volume(elem, c,
+                                            (double)value / MAP_VOL_RES, dir);
 }
 
 static const struct volume_ops_set vol_ops[2] = {
@@ -315,29 +353,42 @@ static const struct volume_ops_set vol_ops[2] = {
                .has_volume = snd_mixer_selem_has_playback_volume,
                .v = {{ snd_mixer_selem_get_playback_volume_range,
                        snd_mixer_selem_get_playback_volume,
-                       snd_mixer_selem_set_playback_volume },
+                       set_playback_raw_volume },
                      { snd_mixer_selem_get_playback_dB_range,
                        snd_mixer_selem_get_playback_dB,
-                       set_playback_dB }},
+                       set_playback_dB },
+                     { get_mapped_volume_range,
+                       get_playback_mapped_volume,
+                       set_playback_mapped_volume },
+               },
        },
        {
                .has_volume = snd_mixer_selem_has_capture_volume,
                .v = {{ snd_mixer_selem_get_capture_volume_range,
                        snd_mixer_selem_get_capture_volume,
-                       snd_mixer_selem_set_capture_volume },
+                       set_capture_raw_volume },
                      { snd_mixer_selem_get_capture_dB_range,
                        snd_mixer_selem_get_capture_dB,
-                       set_capture_dB }},
+                       set_capture_dB },
+                     { get_mapped_volume_range,
+                       get_capture_mapped_volume,
+                       set_capture_mapped_volume },
+               },
        },
 };
 
+static int std_vol_type = VOL_RAW;
+
 static int set_volume_simple(snd_mixer_elem_t *elem,
                             snd_mixer_selem_channel_id_t chn,
                             char **ptr, int dir)
 {
        long val, orig, pmin, pmax;
        char *p = *ptr, *s;
-       int invalid = 0, err = 0, vol_type = VOL_RAW;
+       int invalid = 0, percent = 0, err = 0;
+       int vol_type = std_vol_type;
+       double scale = 1.0;
+       int correct = 0;
 
        if (! vol_ops[dir].has_volume(elem))
                invalid = 1;
@@ -347,10 +398,6 @@ static int set_volume_simple(snd_mixer_elem_t *elem,
        if (*p == '\0' || (!isdigit(*p) && *p != '-'))
                goto skip;
 
-       if (! invalid &&
-           vol_ops[dir].v[VOL_RAW].get_range(elem, &pmin, &pmax) < 0)
-               invalid = 1;
-
        s = p;
        val = strtol(s, &p, 10);
        if (*p == '.') {
@@ -358,32 +405,37 @@ static int set_volume_simple(snd_mixer_elem_t *elem,
                strtol(p, &p, 10);
        }
        if (*p == '%') {
-               if (! invalid)
-                       val = (long)convert_prange1(strtod(s, NULL), pmin, 
pmax);
+               percent = 1;
                p++;
        } else if (p[0] == 'd' && p[1] == 'B') {
-               if (! invalid) {
-                       val = (long)(strtod(s, NULL) * 100.0);
-                       vol_type = VOL_DB;
-                       if (vol_ops[dir].v[vol_type].get_range(elem, &pmin, 
&pmax) < 0)
-                               invalid = 1;
-               }
+               vol_type = VOL_DB;
                p += 2;
-       }
+               scale = 100;
+       } else
+               vol_type = VOL_RAW;
+
+       val = (long)(strtod(s, NULL) * scale);
+       if (vol_ops[dir].v[vol_type].get_range(elem, &pmin, &pmax) < 0)
+               invalid = 1;
+       if (percent)
+               val = (long)convert_prange1(val, pmin, pmax);
        if (*p == '+' || *p == '-') {
                if (! invalid) {
                        if (vol_ops[dir].v[vol_type].get(elem, chn, &orig) < 0)
                                invalid = 1;
-                       if (*p == '+')
+                       if (*p == '+') {
                                val = orig + val;
-                       else
+                               correct = -1;
+                       } else {
                                val = orig - val;
+                               correct = 1;
+                       }
                }
                p++;
        }
        if (! invalid) {
                val = check_range(val, pmin, pmax);
-               err = vol_ops[dir].v[vol_type].set(elem, chn, val);
+               err = vol_ops[dir].v[vol_type].set(elem, chn, val, correct);
        }
  skip:
        if (*p == ',')
@@ -711,15 +763,33 @@ static int controls(int level)
        return 0;
 }
 
+static void show_selem_volume(snd_mixer_elem_t *elem, 
+                             snd_mixer_selem_channel_id_t chn, int dir,
+                             long min, long max)
+{
+       long raw, val;
+       vol_ops[dir].v[VOL_RAW].get(elem, chn, &raw);
+       if (std_vol_type == VOL_RAW)
+               val = convert_prange(raw, min, max);
+       else {
+               vol_ops[dir].v[std_vol_type].get(elem, chn, &val);
+               val = convert_prange(val, 0, MAP_VOL_RES);
+       }
+       printf(" %li [%li%%]", raw, val);
+       if (!vol_ops[dir].v[VOL_DB].get(elem, chn, &val)) {
+               printf(" [");
+               print_dB(val);
+               printf("]");
+       }
+}
+
 static int show_selem(snd_mixer_t *handle, snd_mixer_selem_id_t *id, const 
char *space, int level)
 {
        snd_mixer_selem_channel_id_t chn;
        long pmin = 0, pmax = 0;
        long cmin = 0, cmax = 0;
-       long pvol, cvol;
        int psw, csw;
        int pmono, cmono, mono_ok = 0;
-       long db;
        snd_mixer_elem_t *elem;
        
        elem = snd_mixer_find_selem(handle, id);
@@ -868,13 +938,7 @@ static int show_selem(snd_mixer_t *handle, 
snd_mixer_selem_id_t *id, const char
                                mono_ok = 1;
                        }
                        if (snd_mixer_selem_has_common_volume(elem)) {
-                               snd_mixer_selem_get_playback_volume(elem, 
SND_MIXER_SCHN_MONO, &pvol);
-                               printf(" %s", get_percent(pvol, pmin, pmax));
-                               if (!snd_mixer_selem_get_playback_dB(elem, 
SND_MIXER_SCHN_MONO, &db)) {
-                                       printf(" [");
-                                       print_dB(db);
-                                       printf("]");
-                               }
+                               show_selem_volume(elem, SND_MIXER_SCHN_MONO, 0, 
pmin, pmax);
                        }
                        if (snd_mixer_selem_has_common_switch(elem)) {
                                snd_mixer_selem_get_playback_switch(elem, 
SND_MIXER_SCHN_MONO, &psw);
@@ -891,13 +955,7 @@ static int show_selem(snd_mixer_t *handle, 
snd_mixer_selem_id_t *id, const char
                                if (snd_mixer_selem_has_playback_volume(elem)) {
                                        printf(" Playback");
                                        title = 1;
-                                       
snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &pvol);
-                                       printf(" %s", get_percent(pvol, pmin, 
pmax));
-                                       if 
(!snd_mixer_selem_get_playback_dB(elem, SND_MIXER_SCHN_MONO, &db)) {
-                                               printf(" [");
-                                               print_dB(db);
-                                               printf("]");
-                                       }
+                                       show_selem_volume(elem, 
SND_MIXER_SCHN_MONO, 0, pmin, pmax);
                                }
                        }
                        if (!snd_mixer_selem_has_common_switch(elem)) {
@@ -919,13 +977,7 @@ static int show_selem(snd_mixer_t *handle, 
snd_mixer_selem_id_t *id, const char
                                if (snd_mixer_selem_has_capture_volume(elem)) {
                                        printf(" Capture");
                                        title = 1;
-                                       
snd_mixer_selem_get_capture_volume(elem, SND_MIXER_SCHN_MONO, &cvol);
-                                       printf(" %s", get_percent(cvol, cmin, 
cmax));
-                                       if 
(!snd_mixer_selem_get_capture_dB(elem, SND_MIXER_SCHN_MONO, &db)) {
-                                               printf(" [");
-                                               print_dB(db);
-                                               printf("]");
-                                       }
+                                       show_selem_volume(elem, 
SND_MIXER_SCHN_MONO, 1, cmin, cmax);
                                }
                        }
                        if (!snd_mixer_selem_has_common_switch(elem)) {
@@ -946,13 +998,7 @@ static int show_selem(snd_mixer_t *handle, 
snd_mixer_selem_id_t *id, const char
                                        continue;
                                printf("%s%s:", space, 
snd_mixer_selem_channel_name(chn));
                                if (!pmono && !cmono && 
snd_mixer_selem_has_common_volume(elem)) {
-                                       
snd_mixer_selem_get_playback_volume(elem, chn, &pvol);
-                                       printf(" %s", get_percent(pvol, pmin, 
pmax));
-                                       if 
(!snd_mixer_selem_get_playback_dB(elem, chn, &db)) {
-                                               printf(" [");
-                                               print_dB(db);
-                                               printf("]");
-                                       }
+                                       show_selem_volume(elem, chn, 0, pmin, 
pmax);
                                }
                                if (!pmono && !cmono && 
snd_mixer_selem_has_common_switch(elem)) {
                                        
snd_mixer_selem_get_playback_switch(elem, chn, &psw);
@@ -964,13 +1010,7 @@ static int show_selem(snd_mixer_t *handle, 
snd_mixer_selem_id_t *id, const char
                                                if 
(snd_mixer_selem_has_playback_volume(elem)) {
                                                        printf(" Playback");
                                                        title = 1;
-                                                       
snd_mixer_selem_get_playback_volume(elem, chn, &pvol);
-                                                       printf(" %s", 
get_percent(pvol, pmin, pmax));
-                                                       if 
(!snd_mixer_selem_get_playback_dB(elem, chn, &db)) {
-                                                               printf(" [");
-                                                               print_dB(db);
-                                                               printf("]");
-                                                       }
+                                                       show_selem_volume(elem, 
chn, 0, pmin, pmax);
                                                }
                                        }
                                        if 
(!snd_mixer_selem_has_common_switch(elem)) {
@@ -988,13 +1028,7 @@ static int show_selem(snd_mixer_t *handle, 
snd_mixer_selem_id_t *id, const char
                                                if 
(snd_mixer_selem_has_capture_volume(elem)) {
                                                        printf(" Capture");
                                                        title = 1;
-                                                       
snd_mixer_selem_get_capture_volume(elem, chn, &cvol);
-                                                       printf(" %s", 
get_percent(cvol, cmin, cmax));
-                                                       if 
(!snd_mixer_selem_get_capture_dB(elem, chn, &db)) {
-                                                               printf(" [");
-                                                               print_dB(db);
-                                                               printf("]");
-                                                       }
+                                                       show_selem_volume(elem, 
chn, 1, cmin, cmax);
                                                }
                                        }
                                        if 
(!snd_mixer_selem_has_common_switch(elem)) {
@@ -1927,6 +1961,8 @@ int main(int argc, char *argv[])
                {"version", 0, NULL, 'v'},
                {"abstract", 1, NULL, 'a'},
                {"stdin", 0, NULL, 's'},
+               {"raw-volume", 0, NULL, 'R'},
+               {"mapped-volume", 0, NULL, 'M'},
                {NULL, 0, NULL, 0},
        };
 
@@ -1934,7 +1970,7 @@ int main(int argc, char *argv[])
        while (1) {
                int c;
 
-               if ((c = getopt_long(argc, argv, "hc:D:qidnva:s", long_option, 
NULL)) < 0)
+               if ((c = getopt_long(argc, argv, "hc:D:qidnva:sRM", 
long_option, NULL)) < 0)
                        break;
                switch (c) {
                case 'h':
@@ -1987,6 +2023,12 @@ int main(int argc, char *argv[])
                case 's':
                        read_stdin = 1;
                        break;
+               case 'R':
+                       std_vol_type = VOL_RAW;
+                       break;
+               case 'M':
+                       std_vol_type = VOL_MAP;
+                       break;
                default:
                        fprintf(stderr, "Invalid switch or option needs an 
argument.\n");
                        morehelp++;



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to