Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Alsa-programming: Problem with snd_pcm_t

1 view
Skip to first unread message

wolfgang bauer

unread,
Dec 19, 2019, 2:55:02 AM12/19/19
to
Hi

I want to have an array of PCM-Handles. As example for the function snd_pcm_open.

The type of this handle is: snd_pcm_t

And snd_pcm_t is this:

typedef struct _snd_pcm snd_pcm_t

(according to:
https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#ga919e634deecd855b6e2e15174e70d3ea
https://www.alsa-project.org/alsa-doc/alsa-lib/pcm_8h_source.html)


But what is the _snd_pcm-Structure ?

I can't find anything.



Now my problem:

I can do this: snd_pcm_t test;

But the following gives me an error: snd_pcm_t test[10];

So I can define a single structure but no array ?

This makes no sense for me.



Sieghard Schicktanz

unread,
Dec 19, 2019, 2:13:05 PM12/19/19
to
Hallo wolfgang,

Du schriebst am Thu, 19 Dec 2019 08:55:00 +0100:

> I want to have an array of PCM-Handles. As example for the function
...
> But what is the _snd_pcm-Structure ?

Probabely an "opaque structure".

> I can't find anything.

That's the rationale for these. The user shouldn't have the _need_ for more.

> Now my problem:
>
> I can do this: snd_pcm_t test;
>
> But the following gives me an error: snd_pcm_t test[10];
>
> So I can define a single structure but no array ?

Try an array of pointers to "snd_pcm_t".

> This makes no sense for me.

It doesn't make much sense in a shell group in any case, but the reason
"might" be that the compiler has exactly as much information as you have to
create a correctly sized array of these structures, i.e. none at all

BTW, above that all, this is a german "speaking" group

--
--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------

Rainer Weikusat

unread,
Dec 19, 2019, 2:33:30 PM12/19/19
to
Sieghard Schicktanz <Sieghard....@SchS.de> writes:
> Du schriebst am Thu, 19 Dec 2019 08:55:00 +0100:
>
>> I want to have an array of PCM-Handles. As example for the function
> ...
>> But what is the _snd_pcm-Structure ?
>
> Probabely an "opaque structure".
>
>> I can't find anything.
>
> That's the rationale for these. The user shouldn't have the _need_ for more.
>
>> Now my problem:
>>
>> I can do this: snd_pcm_t test;
>>
>> But the following gives me an error: snd_pcm_t test[10];
>>
>> So I can define a single structure but no array ?
>
> Try an array of pointers to "snd_pcm_t".
>
>> This makes no sense for me.
>
> It doesn't make much sense in a shell group in any case, but the reason
> "might" be that the compiler has exactly as much information as you have to
> create a correctly sized array of these structures, i.e. none at all

Passt nicht zum Beispiel: Falls ein einzelnes Objekt dieses Typs
definiert werden kann, kann auch ein Feld von solchen Objekten definiert
werden. Richtigen Code und/ oder die echte Fehlermeldung zu posten waere
hier sinnvoll.

wolfgang bauer

unread,
Dec 19, 2019, 2:42:58 PM12/19/19
to
Am 19.12.19 um 19:45 schrieb Sieghard Schicktanz:


>> I want to have an array of PCM-Handles. As example for the function
> ...
>> But what is the _snd_pcm-Structure ?
>
> Probabely an "opaque structure".


Ja, das dachte ich mir dann auch. Um weiterzukommen, bin ich prinzipiell den Weg gegangen, den
du hier vorschlägst:


> Try an array of pointers to "snd_pcm_t".

Ich lege ein "unsigned long"-Pointer-Array an und caste dann dort, wo es nötig ist. Die Sache
funktioniert nun.




> BTW, above that all, this is a german "speaking" group


Fiel mir zu spät auf, das ich in die falsche Gruppe gepostet hatte. Ich wollte in die
linux-mint-Gruppe (englischsprachig), weil da mehr los ist und Programmierfragen von Zeit zu Zeit
auch dort
anzutreffen sind.


wolfgang bauer

unread,
Dec 19, 2019, 2:50:01 PM12/19/19
to
Am 19.12.19 um 20:33 schrieb Rainer Weikusat:
Das hatte ich gepostet:

snd_pcm_t test; Funktioniert.

snd_pcm_t test[10]; Funktioniert nicht.

Im zweiten Fall reklamiert der Compiler eine "unvollständige" Struktur. Ich dachte genau wie du, das
wenn eine einzelne Struktur anlegbar ist, ein Array genauso möglich sein sollte. Als ich nirgends
den Strukturaufbau fand, dachte ich in die Richtung, die Sieghard beschrieb.


Ich habe hier voll zitiert, weil es bei dieser technischen Seltsamkeit der besseren Übersicht dient.

Eventuell ist das ein compilerspezifisches Verhalten ?!

Ich habe hier den gnu gcc unter CodeLite im Einsatz.







Rainer Weikusat

unread,
Dec 19, 2019, 4:46:08 PM12/19/19
to
Das geht so nicht. Falls snd_pcm_t als

typedef struct _snd_pcm snd_pcm_t

definiert ist, kann man keine Objekte dieses Typs erzeugen, weil deren
Groesse nicht bekannt ist. Hier muss irgendein ein Irrtum oder eine
Verwechslung vorliegen, die sich wohl aufklaeren wuerde, wenn man den
tatsaechliche Code saehe.

wolfgang bauer

unread,
Dec 19, 2019, 5:40:04 PM12/19/19
to
Am 19.12.19 um 22:45 schrieb Rainer Weikusat:

>>> Passt nicht zum Beispiel: Falls ein einzelnes Objekt dieses Typs
>>> definiert werden kann, kann auch ein Feld von solchen Objekten definiert
>>> werden. Richtigen Code und/ oder die echte Fehlermeldung zu posten waere
>>> hier sinnvoll.
>>>
>>
>> Das hatte ich gepostet:
>>
>> snd_pcm_t test; Funktioniert.
>>
>> snd_pcm_t test[10]; Funktioniert nicht.
>>
>> Im zweiten Fall reklamiert der Compiler eine "unvollständige"
>> Struktur.
>
> Das geht so nicht. Falls snd_pcm_t als
>
> typedef struct _snd_pcm snd_pcm_t
>
> definiert ist, kann man keine Objekte dieses Typs erzeugen, weil deren
> Groesse nicht bekannt ist. Hier muss irgendein ein Irrtum oder eine
> Verwechslung vorliegen, die sich wohl aufklaeren wuerde, wenn man den
> tatsaechliche Code saehe.


Kommando zurück. Du hast Recht. Im Rahmen meiner Experimente ist mir entgangen, das ich

snd_pcm_t test;

als Zeiger deklariert hatte, also so: snd_pcm_t *test;

während ich übersah, das ich das Array als Array aus "Strukturen" deklarierte.


snd_pcm_t test funktioniert also genausowenig, wie snd_pcm_t test[123]

snd_pcm_t *test und wie snd_pcm_t *test[123] hingegen funktionieren beide.


Ich wollte die ganze Device-Vorbereitung für die Soundausgabe in eine einfach zu bedienende Funktion
einpacken, wobei ich bei der Zeigerübergabe im Zusammenspiel mit meiner Funktion für snd_pcm_open
zunächst Probleme mit besagtem Datentyp bekam. (Mit dem erwähnten Workaround ist das Problem
gelöst).

Sorry nochmal für meine Schlafmützigkeit ;-)










Friedhelm Waitzmann

unread,
Dec 20, 2019, 11:01:00 AM12/20/19
to
[
struct _snd_pcm; /* Opakes Struct */
typedef struct _snd_pcm snd_pcm_t;
]

wolfgang bauer:
>Am 19.12.19 um 19:45 schrieb Sieghard Schicktanz:


>> Probabely an "opaque structure".


>Ja, das dachte ich mir dann auch. Um weiterzukommen, bin ich
>prinzipiell den Weg gegangen, den du hier vorschlägst:


>> Try an array of pointers to "snd_pcm_t".

>Ich lege ein "unsigned long"-Pointer-Array an und caste dann
>dort, wo es nötig ist.

Ich meine mich zu erinnern, dass es nicht garantiert ist, dass
ein »struct structname *« ohne Informationsverlust in einen
»unsigned long *« und zurück gewandelt werden kann. Es ist nicht
ausgeschlossen, dass »unsigned long«‐Objekte mit strikterem
Alignment angelegt werden als »struct structname«‐Objekte.
Deshalb kann es auch durchaus sein, dass zur Speicherung eines
»unsigned long *« weniger Bits verwendet werden als zur
Speicherung eines Zeigers auf ein Struct.

Desweiteren muss das Bitmuster eines Zeigers auf ein opak
deklariertes »struct mystruct«‐Objekt mit dem eines Zeigers auf
dasselbe, aber nicht opak deklarierte, Objekt übereinstimmen,
damit im folgenden Beispiel module.h die Deklaration von
myfunction zu ihrer Implementierung in module.c passt.

module.h:

struct my_struct;

extern void myfunction (struct mystruct *);

module.c:

#include "module.h"

struct my_struct
{
[…]
};

void myfunction (struct mystruct *p)
{
[…]
};

Weil der Compiler von einem opaken Struct genau nichts weiß, muss
er deshalb für jegliche (auch nicht opake) Structs für die
Bitdarstellung von Zeigern darauf das lascheste Alignment
annehmen, das bei Structs auftreten kann, selbst wenn ein
konkretes, nicht opak deklariertes, Struct strikter ausgerichtet
wird und deshalb ein Zeiger darauf mit weniger Bits dargestellt
werden könnte.

>Die Sache funktioniert nun.

Dann hast Du Glück gehabt. Mach's lieber richtig.

Ich erinnere mich an einen Prozessor, bei dem durch Type‐Casts
von »long int *« (Zeiger auf ein 4‐Bite‐Integer) auf »short int
*« (Zeiger auf ein 2‐Byte‐Integer) oder durch Type‐Casts von
»short int *« auf »char *« die Bitdarstellung des Zeigers sich
jeweils änderte. Wenn man das Bitmuster des Zeigerwertes als
Integer interpretierte, ergab sich bei diesen Type‐Casts eine
Verdopplung. Offenbar wurden »char«‐Objekte an ungeraden oder
geraden Adressen angelegt, »short int«‐Objekte aber nur an
geraden und »long int«‐Objekte nur an durch 4 teilbaren Adressen.



Friedhelm

wolfgang bauer

unread,
Dec 20, 2019, 8:00:13 PM12/20/19
to
Am 20.12.19 um 17:01 schrieb Friedhelm Waitzmann:

>> Die Sache funktioniert nun.
>
> Dann hast Du Glück gehabt. Mach's lieber richtig.


Danke für deine Erörterungen. Mir war auch nicht ganz wohl bei meiner Lösung.

Wie ich jetzt, im Nachhinein, feststellen muss, hatte ich mich verzettelt und aufgrund
einer Unachtsamkeit ein Problem gefunden, das gar nicht existiert. Statt mich auf die
Struktur "snd_pcm_t" als solche zu konzentrieren, löst sich alles in Wohlgefallen auf,
wenn ich nur mit Zeigern darauf arbeite.

Wie bescheuert sieht das nun aus .. aber mein lauffähiges Programm bleibt lauffähig, wenn ich
einfach aus einem "unsigned long **" ein "snd_pcm_t **" mache ;-)

Wem sowas noch nicht passierte, der werfe das erste Byte ;-)





0 new messages