From alsa-devel-owner@alsa.jcu.cz  Tue Mar 24 02:22:57 1998
Received: from sunu450.rz.ruhr-uni-bochum.de (sunu450.rz.ruhr-uni-bochum.de [134.147.222.33])
	by marvin.jcu.cz (8.8.8/8.8.8) with SMTP id CAA00312
	for <alsa-devel@jcu.cz>; Tue, 24 Mar 1998 02:22:38 +0100
Received: (qmail 15299 invoked from network); 24 Mar 1998 01:22:37 -0000
Received: from dialppp-1-86.rz.ruhr-uni-bochum.de (HELO localhost) (root@134.147.1.86)
  by mailhost.rz.ruhr-uni-bochum.de with SMTP; 24 Mar 1998 01:22:37 -0000
Received: by ruhr-uni-bochum.de
	via sendmail with stdio
	id <m0yHHYj-000NLuC@localhost> (Debian Smail3.2.0.101)
	for alsa-devel@jcu.cz; Tue, 24 Mar 1998 01:27:17 +0100 (CET) 
Message-ID: <19980324012717.02641@flora>
Date: Tue, 24 Mar 1998 01:27:17 +0100
From: Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>
To: alsa-devel@jcu.cz
Subject: Re: C++ API premises...
References: <19980323040241.64574@flora> <Pine.LNX.3.96.980323132536.446C-100000@entry.jcu.cz>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
In-Reply-To: <Pine.LNX.3.96.980323132536.446C-100000@entry.jcu.cz>; from Jaroslav Kysela on Mon, Mar 23, 1998 at 02:20:00PM +0100
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

On Mon, Mar 23, 1998 at 02:20:00PM +0100, Jaroslav Kysela wrote:
> On Mon, 23 Mar 1998, Marcus Brinkmann wrote:
> 
> > I thought about this. It seems that playback & record info require a valid
> > pcm handle. Jaroslav, is it possbile to move the playback & record info out
> > of the pcm code and in the control code? Another possibility (probably
> > easier to implement, if it is at all possible) would be a fourth open mode
> > SND_PCM_OPEN_INFO, that is non-blocking and allows only snd_pcm*info to be
> > called.
> 
> I think that this should be implemented to control interface rather that
> special open mode for pcm interface, but I don't know if this is really
> needed. Info about playback & record will application use in most cases
> only if really require it. In this situation it should open pcm device for
> use and thus get playback & record info.
> 
> Control interface is mainly designed for getting basic (not extended)
> informations about other interfaces/devices.

Let's take a look at the information the application can get:

 int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info )

    struct snd_pcm_info {
      unsigned int type;                    /* soundcard type */
      unsigned int flags;                   /* see SND_PCM_INFO_XXXX */
      unsigned char id[32];                 /* ID of this PCM device */
      unsigned char name[80];               /* name of this device */
      unsigned char reserved[64];           /* reserved for future use */
    };

    #define SND_PCM_INFO_CODEC              0x00000001
    #define SND_PCM_INFO_DSP                SND_PCM_INFO_CODEC
    #define SND_PCM_INFO_MMAP               0x00000002      /* reserved */
    #define SND_PCM_INFO_PLAYBACK           0x00000100
    #define SND_PCM_INFO_RECORD             0x00000200
    #define SND_PCM_INFO_DUPLEX             0x00000400
    #define SND_PCM_INFO_DUPLEX_LIMIT       0x00000800      /* rate for playback & record are same * 

The only relevant technical information that can be evaluated by the
application is the field "flags". It gives information which of the
three open modes (playback, record and duplex) are supported.
But it does not give any information if the device is good enough
for the application at all.

The (identical) playback and record info structures have:
    #define SND_PCM_PINFO_BATCH             0x00000001
    #define SND_PCM_PINFO_8BITONLY          0x00000002
    #define SND_PCM_PINFO_16BITONLY         0x00000004

    struct snd_pcm_playback_info {
      unsigned int flags;                   /* see SND_PCM_PINFO_XXXX */
      unsigned int formats;                 /* supported formats */
      unsigned int min_rate;                /* min rate (in Hz) */
      unsigned int max_rate;                /* max rate (in Hz) */
      unsigned int min_channels;            /* min channels (probably always 1) */
      unsigned int max_channels;            /* max channels */
      unsigned int buffer_size;             /* playback buffer size */
      unsigned int min_fragment_size;       /* min fragment size in bytes */
      unsigned int max_fragment_size;       /* max fragment size in bytes */
      unsigned int fragment_align;          /* align fragment value */
      unsigned char reserved[64];           /* reserved for future use */
    };

This will give the application a hint about the quality. Before attempting
to playback 48kHz (DAT) samples, it would be better to look for a device that can
playback at such a rate, rather than opening blindly a random device.

The general pcm_info structure can give a hint about the direction the
device supports, but for a finer graduation between the devices the playback
and recording infos would be useful, IMO. Even when a device is busy, it
would be nice to look at the capabilities of the device (for status reports,
lists of all devices etc.)

> > Another feature on my wishlist would be a more usable information field in
> > the structure snd_ctl_hw_info. I get "card1" as the id and
> > "Sound Blaster 16 at 0x220, irq 5, dma 1&5" as the name. Both are not very
> > useful for applications to display. If it is assured that the info part of
> > the name is always introduced by "at", this would probably be sufficient
> > (as this can be filtered).
> 
> ID's & names of devices/soundcards:
> 
> I know that it should be implemented better. It's one from things to do.. 
> 
> What about (example for SB16):
> 
> snd_ctl_hw_info -> id = "card1";

If we have an abbreviation here...

  snd_ctl_hw_info -> abbreviation = "SB16"; /* maybe "SB 16" */

> snd_ctl_hw_info -> shortname = "Sound Blaster 16";
> snd_ctl_hw_info -> longname = "Sound Blaster 16 at 0x220, irq 5, dma 1&5";
> 
> snd_mixer_info -> name = "CTL1745";

... it could be used here...
                  name = "SB16 DSP 4.16";
                  name = "SB16 ASP";

> snd_pcm_info -> name = "SB DSP 4.16";	(device 0)
> snd_pcm_info -> name = "SB ASP";	(device 1)
> 
> Application can show to user about mixer & pcm devices:
> 
> card1: Sound Blaster 16 / CTL1745
> 
> card1: Sound Blaster 16 / SB DSP 4.16
> card1: Sound Blaster 16 / SB ASP
> 
> Note that pcm device 1 is only fiction at this moment ;-)
> 
> About ID's:
> 
> snd_ctl_hw_info -> id
> 
> This is probably most interresant string.. This string should be modified
> by user for module.. This string can exactly identifies soundcard rather
> that soundcard # (for example if sound modules for more that two
> soundcard are loaded to kernel in some cases in reverse order).. I'm
> assuming this use if user want identify soundcard with string for
> applications rather than with soundcard #. Any comments?

Ah. Okay, if the user can change the value of Id at insmod time, this is
a nice thing. I find your use of strings rather than constants a bit
unusual, but very likely I haven't realized the real benefit yet.

Below you point out "compatibility and functional code." I'm not
quite sure where the problems with types are (okay, the types never may
change, but isn't the same true for strings?), but I see two problems
with string constants as identifiers (the same applies for SND_MIXER_ID_*).
First is run time efficiency (comparing strings is not very fast)
and second is type checking. A miss-spelled mixer id will only be
caught at run time, not at compile time. Well, the second point is
well adressed by defining SND_MIXER_ID_*, so the applications
should be urged to use them instead the real strings. The first point is
probably not very important in the situations were the comparison is done.

Mmmh. I have the feeling that I didn't understand you at all. Sorry for
being so dumb, but could you please explain me a bit more detailed, why
string constants are preferable? I think I'm missing something obvious...

> snd_mixer_info -> id
> snd_pcm_info -> id
> 
> It will contains id for lowlevel code. Probably not interesting for normal
> application.
> 
> > A probably cleaner solution would be a char* array (similar to the error
> > messages) that is referenced by the type of the card (as defined in
> > sounddetect.h). the kernel driver code could reference this, too (I found 12
> > literal copies of "Sound Blaster 16" spreaded over the kernel code, namely
> > cards/sb16.c, detect/sb.c, lowlevel/sb/sb16.c, lowlevel/sb/sb.c, although
> > some of them have been suplemented by device names ("DSP")).
>
> I preffer rather string that some constant. Note that sounddetect.h is
> mainly designed for application which will manage driver modules and not
> for sound application. Type value should be used in last way...
> The main reason is compatibity and functional code. Old code can pass to
> application right string with soundcard name for new sound driver etc....
> 
> 					Jaroslav

-- 
"Rhubarb is no Egyptian god."        Debian GNU/Linux        finger brinkmd@ 
Marcus Brinkmann                   http://www.debian.org    master.debian.org
Marcus.Brinkmann@ruhr-uni-bochum.de                        for public  PGP Key
http://homepage.ruhr-uni-bochum.de/Marcus.Brinkmann/       PGP Key ID 36E7CD09

