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. #41
    Membre éprouvé
    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
    Points : 1 072
    Points
    1 072
    Par défaut
    le supprimer oui mais le remplacer par "const" serait plus juste puisque
    Citation Envoyé par Andnotor
    afPeakValues n'est pas modifié, c'est le tableau pointé qui l'est.
    Cordialement,
    @+

  2. #42
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    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 : 287
    Points : 164
    Points
    164
    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.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    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.

  4. #44
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    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 : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Oui... mais non ! Delphi 6 Personal Edition est têtu ! Voici le résultat de compilation, avec cette déclaration:
    Nom : aa1.png
Affichages : 217
Taille : 27,7 Ko
    et la déclaration!:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      IAudioMeterInformation = interface(IUnknown)
        ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
        function GetPeakValue(out pfPeak: Single): HRESULT; stdcall;
        function GetMeteringChannelCount(out pnChannelCount: UINT): HRESULT; stdcall;
    //    function GetChannelsPeakValues(u32ChannelCount: UINT; out afPeakValues: pSingle): HRESULT; stdcall;    // version 1
    //    function GetChannelsPeakValues(u32ChannelCount: UINT; out afPeakValues): HRESULT; stdcall;    //version 2
        function GetChannelsPeakValues(u32ChannelCount: UINT; afPeakValues: pSingle): HRESULT; stdcall;    //version 3
        function QueryHardwareSupport(out pdwHardwareSupportMask: UINT): HRESULT; stdcall;
      end;

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Etrange alors

    ChannelVolumes est un pointeur sur un array et non un array et la déclaration est un pointeur sur un single et non un single...

    Bref, laisse comme c'était si ça fonctionne ainsi (je ne suis pas au bureau et ne peut pas tester)

  6. #46
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    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 : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Merci, Andnotor. Je vois enfin plus clair.

    Voici une version plus "lisible", qui passe à la compilation et qui fonctionne en exécution:

    Déclaration de l'interface:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      IAudioMeterInformation = interface(IUnknown)
        ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
        function GetPeakValue(out pfPeak: Single): HRESULT; stdcall;
        function GetMeteringChannelCount(out pnChannelCount: UINT): HRESULT; stdcall;
        function GetChannelsPeakValues(u32ChannelCount: UINT; afPeakValues: pSingle): HRESULT; stdcall;    //version 3
        function QueryHardwareSupport(out pdwHardwareSupportMask: UINT): HRESULT; stdcall;
      end;
    Déclaration des variables globales:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      peak: IAudioMeterInformation = nil;
      SpeakerTimer: TTimer;
      ChannelVolumes: array of Single;          // ces variables sont prévues pour recevoir les PeakValues des deux canaux, par la méthode GetChannelsPeakValues
      pChannelVolumes: pSingle;                 // pointeur sur ChannelVolumes
      pVolumeOutputL, pVolumeOutputR, pVolume: pinteger;   // <=== utilisé pour retourner dynamiquement les peak values deu volume
      MaxOutput: Integer;
      device: IMMDevice;
      deviceEnumerator: IMMDeviceEnumerator;
      nChannels: UINT;
    Etablissement de la connexion:
    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
    function InitSpeakerControl(time, MaxV: integer; poutL, poutR, pVol: pinteger):integer; stdcall; export;
    var
        n: integer;
    begin
      SpeakerTimer := TTimer.Create(nil);
      SpeakerTimer.Enabled := False;
      SpeakerTimer.OnTimer := TDummyForm.Timer1Timer;
      SpeakerTimer.Interval:= time;
      MaxOutput := MaxV;
      pVolumeOutputL := poutL;
      pVolumeOutputR := poutR;
      pVolume := pVol;
      CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, deviceEnumerator);
      deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, device);
      device.Activate(IID_IAudioMeterInformation, CLSCTX_ALL, nil, IUnknown(peak));
      peak.GetMeteringChannelCount(nChannels);
      SetLength(ChannelVolumes,nChannels);
      pChannelVolumes := @ChannelVolumes[0];   // <========== chargement du pointeur
      SpeakerTimer.Enabled := true;
     
      result := 0;
    end;
    exports InitSpeakerControl;
    Fonction cherchant les PeakVolumes:
    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
    // 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
      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]
      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
      peak.GetPeakValue(Temp);                  // prendre la valeur instantané du volume global, résultat dans Temp ==> correct !
      HR := peak.GetChannelsPeakValues(nChannels,pChannelVolumes);              // version 3  opérationnelle
      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;
    ...
    Bon, je vais garder la version comme ça. Elle est claire et lisible, et mieux, elle fonctionne.

    Merci à vous tous pour votre aide. Avec le recul, je pense que l'idée maîtresse était de changer la définition de la méthode de l'interface. Ensuite, n'ayant pas vraiment compris, j'ai mal adapté les paramètres. Maintenant, les choses sont claires.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Je te propose encore un dernier test pour supprimer pChannelVolumes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HR := peak.GetChannelsPeakValues(nChannels, pointer(ChannelVolumes));
    pointer() n'est pas la récupération d'une adresse (comme c'est le cas avec pSingle()) mais la conversion d'un pointeur typé en pointeur quelconque, donc compatible avec tout type de pointeur.

    Après je te fiche la paix

  8. #48
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    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 : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Ca marche ! Très bien. Le code en est encore plus simple. Je garde cette version.

    Et... je suis bien content que tu ne m'aies pas "fichu la paix" jusqu'à maintenant - c'était utile et productif ! Merci !

+ 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, 14h33
  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, 08h56
  3. Trouver les fichiers contenant des annotations
    Par lahitsitely78 dans le forum Eclipse Platform
    Réponses: 0
    Dernier message: 18/02/2009, 11h52
  4. Trouver les redirections dans des traces
    Par severine dans le forum Développement
    Réponses: 3
    Dernier message: 21/04/2004, 18h51

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