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

Ada Discussion :

Binding de la bibliothèque portmidi


Sujet :

Ada

  1. #1
    Invité
    Invité(e)
    Par défaut Binding de la bibliothèque portmidi
    Bonjour,

    Je n'ai pas beaucoup cherché, un temps pour tout, alors, j'avais écrit un bout de code pour interfacer la bibliothèque "portmidi" qui permet d'exploiter les périphérique MIDI.

    Je rencontre quelque difficultés et j'ai une question pour le moment : est-il possible de transposer une macro telle que :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #define Pm_Message(status, data1, data2) \
             ((((data2) << 16) & 0xFF0000) | \
              (((data1) << 8) & 0xFF00) | \
              ((status) & 0xFF))

    Mes difficulté sont liée à la déclaration du type PmMessage et PmEvent :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef int32_t PmMessage; /**< see PmEvent */
     
    typedef struct {
        PmMessage      message;
        PmTimestamp    timestamp;
    } PmEvent;
    Comment traduire ceci ?

    Etant donné que Je voudrais si c'est possible, me passer de corps de paquetage.

    Pour vous donner de quoi corriger, je vous poste mon code actuelle (l'ancien en voie de normalisation) :

    Porttime : binding Ada
    Code Ada : 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
     
    with Interfaces.C;
    with System;
     
    package Porttime is
     
       type PtError is(PtNoError,
                       PtHostError,
                       ptAlreadyStarted,
                       ptAlreadyStopped,
                       PtInsufficientMemory);
     
     
       function Pt_Start(Resolution : Integer;
                         PtCallback : System.Address;
                         UserData : System.address) return PtError;
       pragma Import (C, Pt_Start, "Pt_Start");
     
       function Pt_Time return Interfaces.C.Long;
       pragma Import (C, Pt_Time, "Pt_Time");
     
       type Time_Access is access function return Interfaces.C.Long;
       pragma Convention(C, Time_Access);
    end Porttime;


    Portmidi binding Ada
    Code Ada : 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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
     
    with Porttime;
    with System;
    with Interfaces.C;
    use Interfaces.C;
    with System.Address_To_Access_Conversions;
    package Portmidi is
     
     
       type PmError is (pmNoErro,
                        PmHostError,
                        pmInvalidDeviceId,
                        pmInsufficientMemory,
                        pmBufferTooSmall,
                        pmBufferOverflow,
                        pmBadPtr,
                        pmBadData,
                        pmInternalError,
                        PmBufferMaxSize);
     
       function Pm_Initialize return PmError;
       pragma Import (C, Pm_Initialize, "Pm_Initialize");
     
       function Pm_Terminate return PmError;
       pragma Import (C, Pm_Terminate, "Pm_Terminate");
     
       function Pm_HasHostError( PortMidiStream : System.address) return Interfaces.C.Int;
       pragma Import (C, Pm_HasHostError, "Pm_HasHostError");
     
     
       subtype T_ErrorText is Interfaces.C.Char_Array(0..64);   
       function Pm_GetErrorText( Errnum : PmError  ) return T_ErrorText;
       Pragma Import (C, Pm_GetErrorText, "Pm_GetErrorText");
       package ErrorText_Conversion is new System.Address_To_Access_Conversions
         (T_ErrorText);
       use ErrorText_Conversion;
     
       -- void Pm_GetHostErrorText(char * msg, unsigned int len);
     
       type DeviceInfo is
          record
             StructVersion : Integer;
             Interf : System.address;
             Name : System.Address;
             Input : Integer;
             Output : Integer;
             Opened : integer;
          end record;
     
     
       function Pm_CountDevices return Integer;
       pragma Import (C, Pm_CountDevices, "Pm_CountDevices");
     
       function Pm_GetDefaultInputDeviceID return Interfaces.C.int;
       pragma Import (C, Pm_GetDefaultInputDeviceID, "Pm_GetDefaultInputDeviceID");
     
       function Pm_GetDefaultOutputDeviceID return Interfaces.C.Int;
       pragma Import (C, Pm_GetDefaultOutputDeviceID, "Pm_GetDefaultOutputDeviceID");
     
       function Pm_GetDeviceInfo(PmDeviceID : Integer) return System.Address;
       pragma Import (C, Pm_GetDeviceInfo, "Pm_GetDeviceInfo");
     
       package DeviceInfo_Conversion is new System.Address_To_Access_Conversions(DeviceInfo);
       use DeviceInfo_Conversion;
     
    function Pm_OpenInput(PortMidiStream : System.address;
                             PmDeviceID : Integer;
                             InputDriverInfo : Integer;
                             BufferSize : Long_Integer;
                             PmTimeProcPtr : Porttime.Time_access;
                             time_info : System.address) return PmError;
       pragma Import (C, Pm_OpenInput, "Pm_OpenInput");
     
     
       function Pm_OpenOutput(PortMidiStream : System.Address;
                              OutputDevice : Integer;
                              outputDriverInfo : System.address;
                              BufferSize : Long_Integer;
                              Time_Proc : Porttime.Time_access;
                              Time_Info : System.address;
                              latency : Long_integer) return PmError;
       pragma Import (C, Pm_OpenOutput, "Pm_OpenOutput");
     
     
       function Pm_SetFilter(PortMidiStream : System.Address;
                             filters : Long_Integer) return PmError;
       pragma Import (C, Pm_SetFilter, "Pm_SetFilter");
     
       function Pm_SetChannelMask(PortMidiStream : System.Address;
                                  Mask : integer) return PmError;
       pragma Import (C, Pm_SetChannelMask, "Pm_SetChannelMask");
     
       function Pm_Abort( PortMidiStream : System.Address) return PmError;
       pragma Import (C, Pm_Abort, "Pm_Abort");
     
       function Pm_Close( PortMidiStream : System.Address) return PmError;
       pragma Import (C, Pm_Close, "Pm_Close");
     
    end Portmidi;

    Je n'ai jamais testé Pm_OpenInput ni Pm_Openoutput. J'avais fais des function perso.

    S'il vous plaît ? Merci pour vos réponses.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Pour le moment j'ai fait un corps de bibliothèque avec Pm_Message, Status, Data1, Data2 et Channel.

    Voici à quoi ressemble Pm_message qui utilise la fonction Shift_Left de interfaces.

    Code ada : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     function Pm_Message(Status, Data1, Data2 : Interfaces.C.Long) return Interfaces.C.Long is
     
          Message : Unsigned_32 := 0;
          Low     : Unsigned_32 := Unsigned_32(Data2);
          Middle  : Unsigned_32 := Unsigned_32(Data1);
          High    : Unsigned_32 := Unsigned_32(status);
       begin
          Message := ((Shift_Left(Low, 16) and 16#FF0000#) or
                         (Shift_Left(middle, 8) and 16#FF00#) or
                         (high and 16#FF#));
     
          return Interfaces.C.Long(Message);
       end Pm_Message;


    J'ai regarder aussi les fonction Pm_Open, je vous reposte la spécification...
    Faut que je test la fonction Read aussi.
    (j'ai peut-être pas terminé encore, mais j'ai une excuse)

    Code ada : 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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    with Porttime;
    with System;
    with Interfaces.C;
    use Interfaces.C;
    with System.Address_To_Access_Conversions;
    package Portmidi is
     
     
       type PmError is (pmNoErro,
                        PmHostError,
                        pmInvalidDeviceId,
                        pmInsufficientMemory,
                        pmBufferTooSmall,
                        pmBufferOverflow,
                        pmBadPtr,
                        pmBadData,
                        pmInternalError,
                        PmBufferMaxSize);
     
       function Pm_Initialize return PmError;
       pragma Import (C, Pm_Initialize, "Pm_Initialize");
     
       function Pm_Terminate return PmError;
       pragma Import (C, Pm_Terminate, "Pm_Terminate");
     
       function Pm_HasHostError( PortMidiStream : System.address) return Interfaces.C.Int;
       pragma Import (C, Pm_HasHostError, "Pm_HasHostError");
     
     
       subtype T_ErrorText is Interfaces.C.Char_Array(0..256);
       function Pm_GetErrorText( Errnum : PmError  ) return T_ErrorText;
       pragma Import (C, Pm_GetErrorText, "Pm_GetErrorText");
       package ErrorText_Conversion is new System.Address_To_Access_Conversions
         (T_ErrorText);
       use ErrorText_Conversion;
     
     
       type DeviceInfo is
          record
             StructVersion : Integer;
             Interf : System.address;
             Name : System.Address;
             Input : Integer;
             Output : Integer;
             Opened : integer;
          end record;
     
     
       function Pm_CountDevices return Integer;
       pragma Import (C, Pm_CountDevices, "Pm_CountDevices");
     
       function Pm_GetDefaultInputDeviceID return Interfaces.C.int;
       pragma Import (C, Pm_GetDefaultInputDeviceID, "Pm_GetDefaultInputDeviceID");
     
       function Pm_GetDefaultOutputDeviceID return Interfaces.C.Int;
       pragma Import (C, Pm_GetDefaultOutputDeviceID, "Pm_GetDefaultOutputDeviceID");
     
       function Pm_GetDeviceInfo(PmDeviceID : Integer) return System.Address;
       pragma Import (C, Pm_GetDeviceInfo, "Pm_GetDeviceInfo");
     
       package DeviceInfo_Conversion is new System.Address_To_Access_Conversions(DeviceInfo);
       use DeviceInfo_Conversion;
     
     function Pm_Poll( PortMidiStream : System.Address) return PmError;
       pragma Import (C, Pm_Poll, "Pm_Poll");
     
     
     
       function Pm_Message(Status, Data1, Data2 : Interfaces.C.Long) return Interfaces.C.Long;
       function Status(Message : Interfaces.C.long) return Interfaces.C.Long;
       function data1(Message : Interfaces.C.long) return Interfaces.C.Long;
       function Channel(Message : Interfaces.C.Long) return Interfaces.C.Long;
       function data2(Message : Interfaces.C.long) return Interfaces.C.Long;
     
     
     
       type PmEvent is
          record
             Message : Interfaces.C.Long := 0;
             PmTimestamp : Interfaces.C.Long := 0;
          end record;
     
     
       function Pm_Write( PortMidiStream : System.address;
                          Pm_Event : PmEvent;
                          length : Interfaces.C.Long) return PmError ;
       pragma Import (C, Pm_Write, "Pm_Write");
     
     
       function Pm_WriteShort( PortMidiStream : System.address;
                               PmTimestamp : Interfaces.C.long;
                               Msg : Interfaces.C.long) return PmError;
       pragma Import (C, Pm_WriteShort, "Pm_WriteShort");
     
       function Pm_WriteSysEx( PortMidiStream : System.Address;
                               PmTimestamp : Float;
                               Msg : integer) return PmError;
       pragma Import (C, Pm_WriteSysEx, "Pm_WriteSysEx");
     
     
     
    end Portmidi;

    Je vous laisse donc le plaisir d'implémenter les fonctions manquantes.

  3. #3
    Invité
    Invité(e)
    Par défaut Import de Pm_Read
    Evidemment, j'avais oublié l'import de Pm_Read, et qui malheureusement me pose problème.

    Voici mon import :
    Code ada : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Function Pm_Read(PortMidiStream : System.Address;		    
    		    Pm_Event : access PmEvent;
    		    length : Interfaces.C.Long) return PmError ;
    pragma Import (C, Pm_Read, "Pm_Read");

    Mais d'abord, il semble que la fonction Pm_Read ne soit pas bloquante ce qui me pose un premier problème, ça tourne dans le vide. ; Mais j'obtiens une erreur HostError dès la réception de message.

    Mon appel est le suivant :
    Code ada : 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
     
    task body Input is
     
    	 Event : access PmEvent := new PmEvent;
          begin
    	 loop	
    	    declare	       
    	       Pm_Error : PmError;
    	    begin
     
    	         Text_Io.Put_Line("message :" & Long'Image(Event.Message));
    	         Pm_Error := Pm_Read(Address.all, 
    	         			   Event,
                                               1);	       
     
    	         case Pm_Error is
    	         	  when PmNoError =>
    		     accept Send(Message : out Long) do
    			Message := Event.Message;			
    		     end Send;
    	         	  when others =>
    	         	         Text_Io.Put(PmError'Image(Pm_Error));
    	         end case;
    	    end;
    	 end loop;
     
          end Input;


    Alors, j' ai une implémentation un truc que j'ai tiré d'un code C dont je faisais l'import avant.
    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
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    #include "unistd.h"
    #include "portmidi.h"
    #include "porttime.h"
    #include "stdio.h"
     
    #define INPUT_BUFFER_SIZE 100
    #define OUTPUT_BUFFER_SIZE 0
    #define DRIVER_INFO NULL
    #define TIME_PROC ((long (*)(void *)) Pt_Time)
    #define TIME_INFO NULL
    #define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
     
     
     
    long Read_Handler(PortMidiStream *midi) {
      PmError status, length;
      PmEvent buffer[1];
      int i = 0;
      int num = 1;
        /* It is recommended to start timer before Midi; otherwise, PortMidi may
           start the timer with its (default) parameters
         */
      /*TIME_START;*/
     
      /* open input device
        Pm_OpenInput(, 
                     i,
                     DRIVER_INFO, 
                     INPUT_BUFFER_SIZE, 
                     TIME_PROC, 
                     TIME_INFO);*/
     
        /*printf("Midi Input opened. Reading %d Midi messages...\n",num);*/
        Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
        /* empty the buffer after setting filter, just in case anything
           got through */
        while (Pm_Poll(midi)) {
            Pm_Read(midi, buffer, 1);
        }
        /* now start paying attention to messages */
        i = 0; /* count messages as they arrive */
        buffer[0].message = 0;
        while (i < num) {
            status = Pm_Poll(midi);
            if (status == TRUE) {
    	  length = Pm_Read(midi,buffer, 1);
    	  if (length > 0)
    	    i++;            	            	      
    	}        
    	usleep(50);
        }
     
        /* close device (this not explicitly needed in most implementations) */
        /*printf("ready to close...");*/
     
        /*Pm_Close(midi);*/
        /*printf("done closing...");*/
        return buffer[0].message;
    }
    Dans ce code je lie et renvoie 1 seul message normalement, de mémoire.


    Mais je suis paumé, parce que ça n'a rien à voir avec un simple appel à Pm_Read.


    A votre avis, ou est mon erreur ?
    Merci
    Dernière modification par Invité ; 24/07/2012 à 18h25.

  4. #4
    Invité
    Invité(e)
    Par défaut Traduction de la fonction C Read_Handler avec Ada
    Bonjour, j'ai donc transposé la fonction Read_Handler, mais elle me pose encore problème.
    A vrai dire je nais pas testé tous les état de sortie de Pm_Read.
    Donc, tout ce que je sais, c'est que parfois elle plante.

    Voici le code.

    Code ada : 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
     
    procedure Read       (Device : in     Device_Type; Message : out C.Long) is
          Pm_Error : PmError := PmNoError;
          Pm_Event : PmEvent_Access := new PmEvent;
     
       begin     
          if not Device.Initialized then
             raise Not_Initialized;
          end if;
          if Device.Mode /= MIDI_In then
             raise MODE_Error;
          end if;
          Message := 0;
          loop
     
    	 Pm_Error := Pm_Poll(Device.Addr.all);      	 
    	 if Pm_Error /= PmNoError then
    	    Pm_Error := Pm_Read(Device.Addr.All, Pm_Event, 1);            	    		  	       		  	 
     
    	 else
    	    exit;
    	 end if;
          end loop;	   
          loop
    	 Pm_Error := Pm_Poll(Device.Addr.all);                  
    	 if Pm_Error /= Pmnoerror  then	    	    	    
    	    Pm_Error := Pm_Read(Device.Addr.All, Pm_Event, 1);           
    	    if Pm_Error /= Pmnoerror then
    	       Message := Pm_Event.Message;	    	    	       	 
    	       return;
    	    end if;	 
    	 end if;      
    	 delay 0.005;
          end loop;
       end Read;
    Alors, je sais combien ça fais 50 micro seconde, mais ça fonctionne un poil mieux avec 500.

    Le code est relativement bizarre sémantiquemant parlant, mais c'est le reflet du code C simplement.

    J'appelle ce code en boucle pour lire un message MIDI sur un périphérique MIDI.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Je viens ici, parce que je rencontre un problème avec mon binding Ada de portmidi.

    En effet, il m'est actuellement impossible d'utilisé plusieurs instrument simultanément.

    J'obtiens depuis Ada un message d'erreur :
    PortMidi found host error...
    Opération non permise
    type ENTER...PortMidi found host error...
    Opération non permise
    type ENTER...
    Vous trouverez les dernières sources qui n'ont guère changé, à 88.189.147.62/musicals/

    Je sèche complètement sur ce problème depuis 2 semaines.

    Si vous avec un tuyau, Merci.

Discussions similaires

  1. Bind - sous-domaine
    Par _Gabriel_ dans le forum Réseau
    Réponses: 4
    Dernier message: 07/03/2004, 11h54
  2. [MFC]bibliothèques Jpeg
    Par kor dans le forum MFC
    Réponses: 3
    Dernier message: 06/01/2004, 15h08
  3. Bibliothèque Gcc/mingw 2.95.3.6
    Par richard dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 11/10/2003, 22h54
  4. Réponses: 8
    Dernier message: 03/09/2003, 00h47
  5. Bibliothèques et documentation
    Par Anonymous dans le forum OpenGL
    Réponses: 4
    Dernier message: 01/04/2002, 12h24

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