IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Trouver les peak values des deux canaux du haut-parleur


Sujet :

API, COM et SDKs Delphi

  1. #21
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Tu dis:
    EDIT : regarde ce truc, ça doit être facilement transposable en Delphi, j'ai trouvé les noms des fonctions sympathiquement utiles (ou utilement sympathiques, comme tu le sens, )
    J'ai regardé la section intéressante:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
           public void IAudioMeterInformation_GetChannelsPeakValues()
            {
                ExecuteDeviceActivationTest(activation =>
                {
                    UInt32 count;
                    activation.GetMeteringChannelCount(out count);
     
                    var peaks = Enumerable.Repeat(123.456f, (int)count).ToArray();
                    var result = activation.GetChannelsPeakValues(count, peaks);
     
                    AssertCoreAudio.IsHResultOk(result);
                    Assert.IsFalse(peaks.Any(f => f == 123.456f), "One or more channel values was not received.");
                });
            }
    Et j'ai l'impression que je fais exactement ça:
    - récupérer le nombre de anaux dans un integer - j'ai vérifié: la valeur est 2
    - créer une variable en flottant simple de type tableau avec le nombre de canaux - ici, c'est la variable peaks
    - appeler laméthode GetChannelsPeakValues avec ses 3 paramètres "nombre de canaux" et "pointeur vers le tableau"
    Mais mon interprétation reste fragile car je ne suis pas du tout opérationnel en C. J'ai vérifié les différents éléments de la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var peaks = Enumerable.Repeat(123.456f, (int)count).ToArray();
    et ça semble correspondre à ce que je fais, à ceci près qu'ici, le tableau est créé dynamiquement, alors que pour ma part, je le crée en tableau statique de deux éléments.

    Je sèche...

  2. #22
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 164
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 164
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Je sèche...
    Oui...
    Mais quand je disais :
    Citation Envoyé par Jipété Voir le message
    EDIT : regarde ce truc, ça doit être facilement transposable en Delphi, j'ai trouvé les noms des fonctions sympathiquement utiles (ou utilement sympathiques, comme tu le sens, )
    je sous-entendais de démarrer un nouveau projet de test et y traduire le lien donné, pour voir comment ça se comporte avec un minimum d'instructions. La blague y sera peut-être plus facile à cerner.
    Car ce lien, du peu que j'en ai lu, semble être une unité de test.

  3. #23
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Je me heurte toujours au même problème. Mis à part le fait que, dans mon code, je prends également le volume global, la récupération des volumes par canal conduit toujours au même résultat. J'ai conçu mon code en adaptant un code similaire, aidé par la doc de MSN. Et, en toute logique, si la valeur pour le premier canal arrive, celle pour le second doit arriver également. Car, après tout, il s'agit d'un seul et unique appel de la méthode de l'interface, et non deux appels distincts dont un pourrait être mal paramétré.

  4. #24
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 164
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 164
    Par défaut
    Bonsoir,

    si c'est possible, tu devrais générer un projet de test réduit au strict nécessaire et mettant en évidence le problème, tout ça packagé dans un .zip, afin que d'autres puissent tester.

  5. #25
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    C'est une idée. Je vais essayer ça.

  6. #26
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Voilà qui est fait. Un projet complet, opérationnel, réalisé avec Delphi 6 Personal Edition.

    J'y ai inclus les fonctions en question en provenance de ma DLL, sans aucune modification, et je les ai appelées par deux boutons, au lieu de les appeler par n langage externe. Puis, j'ai ajouté un simple timer Delphi nommé Surveillance qui se déclanche toutes les 90 millisecondes. Il va afficher le contenu de mes 3 variables supposées recevoir les PeakVolume du canal gauche et droit ainsi que le PeakVolume global.

    Au démarrage, il ne se passe rien, bien sûr. Il faut cliquer sur "Démarrer" et les 3 valeurs s'affichent. Si le volume général est coupé, les 3 valeurs resten à zéro. Si l'on monte le volume général, il ne se passe toujours rien. Normal. Mais si maintenant un fait jouer un son ou une vidéo quelconque, on voit immédiatement que la canal gauche et le volume général travaillent, mais pas le canal droit.

    Voilà, je ne vois pas ce que je pourrais faire de mieux pour montrer le problème...
    Fichiers attachés Fichiers attachés

  7. #27
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 945
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 945
    Billets dans le blog
    6
    Par défaut
    Une idée de test à la c*** (au cas où éléments du tableau pas "rangés" dans le même sens) :
    déclarer le tableau de singles [0..2]
    passer l'adresse de l'élément d'indice 1
    regarder les 3 valeurs après appel de la fonction

    NB: je n'y crois pas, mais en même temps, on n'a pas d'explication satisfaisante du comportement...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  8. #28
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 164
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 164
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Voilà qui est fait. Un projet complet, opérationnel, réalisé avec Delphi 6 Personal Edition.
    Bien joué.
    Plus qu'à attendre les retours des copains...

    En ce qui me concerne, je suis coincé de chez coincé pour la bonne et simple raison que j'ai des vieilles machines Windows (en machines virtuelles) mais c'est du XP et du 2000, or les API's que tu manipules sont notées chez MS "à partir de Vista",
    J'ai quand même testé dans une Seven (mais elle n'a pas d'outils de développement), et le problème est identique : on est donc au moins sûr que le problème est dans ton code et pas dans ta machine, c'est déjà un point pour avancer.

    Voilà pour ma contribution, je regrette de ne pouvoir aller plus loin...

  9. #29
    Membre émérite
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Par défaut
    Bonjour et bonnes fêtes,

    très bonne idée que celle de créer un projet démo

    je pense avoir trouvé le problème qui se situe au niveau du passage du PSingle à la fonction "peak.GetChannelsPeakValues"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    begin
      ttimer(sender).Enabled := false;          // arrêter le timer, le temps de traiter l'évènement
      ChannelVolumes[0] := 0;                   // assurer que le tableau est bien lis à zéro
      ChannelVolumes[1] := 0;
    // suppression de cette ligne
    //  pVolumes := pSingle(@ChannelVolumes[0]);  // créer le pointeur vers le début du tableau
                                                // si j'ai bien compris la documentation de MSDN, la méthode GetChannelsPeakValues prens 2 paramètres:
                                                // le premier donne le nombre de canaux (deux dans mon cas, et j'ai vérifié le contenu de la variab
     
      peak.GetPeakValue(Temp);                  // prendre la valeur instantané du volume global, résultat dans Temp ==> correct !
    // pour un passage direct    et là ça fonctionne ;)
      HR := peak.GetChannelsPeakValues(nChannels, pSingle(ChannelVolumes[0]));      // prendre les valeurs instantanées des deux canaux <========== Seul [1] est retourné, [2] reste à zéro !
                                                           // un pointeur vers le premier élément d'un tableau de flottants (de type Single)
                                                           // la méthode est supposé remplir le tableau avec les deux valeurs...
    voilà en espérant que ça t'aidera

    Cordialement,
    @+

  10. #30
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 164
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 164
    Par défaut
    Citation Envoyé par Cirec Voir le message
    je pense avoir trouvé le problème qui se situe au niveau du passage du PSingle à la fonction "peak.GetChannelsPeakValues"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // suppression de cette ligne
    //  pVolumes := pSingle(@ChannelVolumes[0]);  // créer le pointeur vers le début du tableau
    // pour un passage direct    et là ça fonctionne ;)
      HR := peak.GetChannelsPeakValues(nChannels, pSingle(ChannelVolumes[0]));      // prendre les valeurs instantanées des deux canaux <========== Seul [1] est retourné, [2] reste à zéro !

    Confirmé sous Seven après compilation avec D7 perso sous 2000


  11. #31
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    YES !!!!!!!!!!!

    C'est vrai - ça marche ! Un grand MERCI à vous, Jipété et Cirec !

    Mais enfin, j ene comprends pas. Caster un élément d'un tableau de single en pSingle - je ne comrprends pas. J'avais pourtant l'impression de construire un pointeur vers le premier élément de mon tableau avec la première ligne que tu supprimes, et dans la deuxième, je passais ce pointeur... Qu'est-ce que ça signifie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pSingle(ChannelVolumes[0])
    Je ne comprends pas vraiment cette expression.

  12. #32
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 164
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 164
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    C'est vrai - ça marche ! Un grand MERCI à toi, Jipété !
    Ben c'est surtout Cirec qu'il faut remercier, c'est lui qui a mis le doigt là où ça faisait mal, et qui va se faire un plaisir de nous expliquer les tréfonds du casting,

    PS : tu penseras à cliquer sur , merci

  13. #33
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Ben c'est surtout Cirec qu'il faut remercier
    Oui, je viens de réaliser, et j'ai rectifié mon message ! C'est déjà bien de voir que des membres du forum s'occupent de mon problème, et en plus trouvent la solution ! C'est super ! Quoique un peu frustrant, car je ne comprends pas pourquoi ça marche et pas ma version du code. Mais Cirec aura sûrement pitié de mon ignorance...

  14. #34
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 969
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 969
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    Caster un élément d'un tableau de single en pSingle - je ne comrprends pas.
    Ce n'est pas un transtypage, un transtypage est l'interprétation d'une donnée sous une autre forme. Ce n'est pas le cas ici, pSingle n'est pas un type mais un pointeur typé. pSingle(ChannelVolumes[0]) retourne donc un pointeur sur le premier élément ChannelVolumes. @ChannelVolumes serait identique pour ton utilisation, la seule différence étant que le pointeur est non typé mais cela n'aurait aucune incidence sur l'appel de la fonction qui n'attend finalement qu'une adresse.

    Partant de là, pSingle(@ChannelVolumes[0]) est un pointeur (pSingle) sur un pointeur (@) et non sur une donnée (ChannelVolumes). Tu as de la chance de ne pas avoir eu de VA.

    Bravo à Cirec , ces histoires de pointeur sont régulièrement à s'arracher les cheveux.

    pSingle (ou tout pointeur typé) est principalement utile dans les déclarations de variables pour permettre leur incrémentation en fonction du type de données. Pour un passage de paramètre, @ est suffisant.

    Tu pourrais maintenant apporter quelques améliorations à ton code. Tu pars du principe qu'il y a deux canaux mais ce n'est qu'une supposition. ChannelVolumes devrait être un array of single et sa taille dépendante de ChannelCount (SetLength). Mais attention, la déclaration d'un tableau dynamique n'étant qu'un pointeur, plus besoin de pSingle ou @.

  15. #35
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Merci beaucoup pour ces explications. Cependant, il reste un point ouvert: mon compilateur n'aime pas beaucoup l'absence du pSingle ou du @. Suivant ton conseil, j'ai défini mon tableau en dynamique, et je l'ai dimensionné en fonction du nombre de canaux, tout en laissant l'appel de ma méthode identique. Ca marche sans problème. Dont acte pour la défintiion du tableau.

    Par contre, tu dis:
    la déclaration d'un tableau dynamique n'étant qu'un pointeur, plus besoin de pSingle ou @
    Et là, mon compilateur ne veut plus:
    Nom : aa1.png
Affichages : 268
Taille : 56,8 Ko
    absence du pSingle et du @ est refusée.

    Ou alors:
    Nom : aa2.png
Affichages : 236
Taille : 71,4 Ko
    idem sans spécifier l'indice.

    Ou alors:
    Nom : aa4.png
Affichages : 262
Taille : 59,2 Ko
    idem juste avec @.

    Voilà ce qui marche:
    Nom : aa3.png
Affichages : 267
Taille : 65,2 Ko

    Est-ce que c'est l'ancien Delphi 6 qui ne comprend pas qu'un tableau dynamique est juste un pointeur, ou est-ce que j'ai mal compris ton message ?

  16. #36
    Membre émérite
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Par défaut
    Citation Envoyé par KlausGunther
    C'est super ! Quoique un peu frustrant, car je ne comprends pas pourquoi ça marche et pas ma version du code. Mais Cirec aura sûrement pitié de mon ignorance...
    re,

    j'aurai bien aimer répondre à ta demande mais je crains de ne pas avoir de réponse a te donner !

    tout ce que je sais c'est que le fait d'avoir mis le doigt sur le "Pointeur sur Pointeur" n'a pas résolu le problème en soi.
    si on passe par une variable intermédiaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pVolumes := pSingle(ChannelVolumes[0]);
    HR := peak.GetChannelsPeakValues(nChannels, pVolumes);
    ça ne fonctionne pas !!!
    par contre HR := peak.GetChannelsPeakValues(nChannels, pSingle(ChannelVolumes[0])); fonctionne

    et ça je ne me l'explique pas .... désolé

    Si quelqu'un a une explication je suis également preneur

    Cordialement,
    @+

  17. #37
    Membre émérite
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Par défaut
    pour illustrer les propos d'AndNotOr
    Mais attention, la déclaration d'un tableau dynamique n'étant qu'un pointeur, plus besoin de pSingle ou @.
    il te faut redéclarer la fonction "GetChannelsPeakValues" ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        function GetChannelsPeakValues(u32ChannelCount: UINT; out afPeakValues): HRESULT; stdcall;
    et du coup tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HR := peak.GetChannelsPeakValues(nChannels, ChannelVolumes[0]);
    Cordialement,
    @+

  18. #38
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Très intéressant ! Un paramètre non typé - je n'aurais jamais pensé à ça ! Mais ça marche - tant mieux.

    MSDN dit:
    afPeakValues [out]

    Pointer to an array of peak sample values. The method writes the peak values for the channels into the array. The array contains one element for each channel in the stream. The peak values are numbers in the normalized range from 0.0 to 1.0.
    Je pensais naturellement que passer un pointer vers un flottant simple correspondrait à la définition. Mais un paramètre non typé ? Là encore, c'est un mystère pour moi. Apparemment, un paramètre non typé est traité comme un pointeur, n'est-ce pas ?

  19. #39
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 969
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 969
    Par défaut
    Supprime le out qui n'a à mon sens pas lieu d'être. afPeakValues n'est pas modifié, c'est le tableau pointé qui l'est.

  20. #40
    Membre éclairé

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 383
    Billets dans le blog
    1
    Par défaut
    Dans ce cas, le compilateur rejette pour cause de manque de type du paramètre:
    Nom : aa1.png
Affichages : 244
Taille : 27,9 Ko

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. trouver les noeuds avec des valeurs nulles
    Par awalter1 dans le forum Général Python
    Réponses: 3
    Dernier message: 28/10/2010, 15h33
  2. Trouver les trous dans des périodes sur la même table
    Par CinePhil dans le forum Requêtes
    Réponses: 5
    Dernier message: 11/04/2009, 09h56
  3. Trouver les fichiers contenant des annotations
    Par lahitsitely78 dans le forum Eclipse Platform
    Réponses: 0
    Dernier message: 18/02/2009, 12h52
  4. Trouver les redirections dans des traces
    Par severine dans le forum Développement
    Réponses: 3
    Dernier message: 21/04/2004, 19h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo