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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 950
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 950
    Par défaut
    Je pensais à un paramètre typé (ou simplement de type pointer si ça devait poser problème), plus proche du prototype et plus parlant à la relecture dans quelques mois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function GetChannelsPeakValues(u32ChannelCount: UINT; afPeakValues: pSingle): HRESULT; stdcall;
     
    var
      ChannelVolumes :array of single;
     
    SetLength(ChannelVolumes, nChannels);
    HR := peak.GetChannelsPeakValues(nChannels, ChannelVolumes);
    Mais si tu es satisfait, pas de soucis

    ps: je ne sais pas quelle est l'influence de const sur une méthode d'interface.

  2. #2
    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 ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 950
    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.

  4. #4
    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 à vous deux ! Je vais creuser cela encore, avec ces informations.

    Voici comment je fais actuellement:
    Déclaration des variables!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      ChannelVolumes: array[0..1] of Single;    // ces variables sont prévues pour recevoir les PeakValues des deux canaux, par la méthode GetChannelsPeakValues
      pVolumes: pSingle;                        // ce pointeur doit pointer sur le premier élément du tableau ci-dessus, et est passé en paramètre à GetChannelsPeakValues
    Appel de la méthode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      ChannelVolumes[0] := 0;                   // assurer que le tableau est bien lis à zéro
      ChannelVolumes[1] := 0;
      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
     
      HR := peak.GetChannelsPeakValues(nChannels,pVolumes);      // 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...
    Et voici la fonction complète dont sont extaits ces codes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    // Ceci est la fonction évènement OnTimer du timer créé lors de la mise en route de la surveillance du volume
    class procedure TDummyForm.Timer1Timer(Sender: TObject);
    var
      ChannelVolumes: array[0..1] of Single;    // ces variables sont prévues pour recevoir les PeakValues des deux canaux, par la méthode GetChannelsPeakValues
      pVolumes: pSingle;                        // ce pointeur doit pointer sur le premier élément du tableau ci-dessus, et est passé en paramètre à GetChannelsPeakValues
      Temp: Single;                             // cette variable reçoit la peak value générale, par la méthode GetPeakValue
      vL, vR, vV: integer;                      // ce sont des variables techniques pour ajuster les valeurs reçues vers l'intervalle imposé [0..MaxOutput]
      s: string;                                // variable temporaire pour afficher le titre - utiliser ici la variable ApplicationTitle NE MARCHE PAS !
      HR: HResult;                              // code retour de la méthode GetChannelsPeakValues
    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;
      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 !
      HR := peak.GetChannelsPeakValues(nChannels,pVolumes);      // 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...
      if nChannels<>2 then showmessage('nChannels='+inttostr(nChannels));
      if HR<>S_OK then begin
        if HR=E_INVALIDARG then showmessage('E_INVALIDARG')
          else if HR=E_POINTER then showmessage('E_POINTER')
            else showmessage('Erreur '+inttostr(integer(HR))+' = '+inttohex(integer(HR),8));
      end;
     
      // sans les deux lignes suivantes, le contenu du tableau ChannelVolumes reste à zéro, même pour le [1].
      // avec ces deux lignes stupides, le [1] est renseigné correctement,, mais le [2] reste toujours à zéro !
      s := ApplicationTitle;
      SendMessage(MainFormHandle,WM_SETTEXT,0,integer(@s[1]));
     
      // traduire en valeurs entre 0 et 100
      vL := Round(ChannelVolumes[0] * MaxOutput);             // valeur canal droit <======== valeur correcte !
      vR := Round(ChannelVolumes[1] * MaxOutput);             // valeur canal droit <======== ici, reste à zéro !
      vV := Round(temp * MaxOutput);                          // valeur canal gauche <====== valeur correcte !
     
      // envoyer ces valeurs dans des variables de l'application, si leur adresse a été passée en paramètre à la fonction InitSpeakerControl
      if pVolumeOutputL<>nil then pVolumeOutputL^ := vL;
      if pVolumeOutputR<>nil then pVolumeOutputR^ := vR;
      if pVolume<>nil then pVolume^ := vV;
      ttimer(sender).Enabled := true;                          // relancer le timer
    end;
    J'avais mis des arrêts et affichages du contenu des variables partout, et particulièrement avant et après l'appel de la méthode. C'est pourquoi je peux affirmer que ChannelVolumes[0] reçoit bien la bonne valeur, et ChannelVolumes[1] reste déspérément à zéro. Et je ne me fie évidemment pas à l'affichage de mon VuMeter que je veux tester, justement, mais au contenu des variables que je surveille par des méthodes traditionnelles.

  5. #5
    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...

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 166
    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.

  7. #7
    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
    Ok. J'ai essayé: ça marche avec CONST et OUT comme préfixe de la déclaration du paramètre si j'omets le type.

    J'ai appris des choses, dans cette discussion ! Merci beaucoup à vous tous. J'en conclus qu'un paramètre passé sans type est interprété comme pointeur non typé et utilisé comme tel par la fonction en iinterne. Bon à savoir.

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

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