Page 1 sur 1

bibliothèque portaudio "accès mémoire invalide"

Publié : lun. 16/juin/2025 23:59
par det_uio
Bonsoir ,

Bibliothèque portaudio "accès mémoire invalide".

Le programme affiche bien le nombre de périphérique mais il bloque à cette ligne :

Debug "Périphérique " + Str(i) + " : " + PeekS(*deviceInfo\name, -1, #PB_Ascii)

J'ai vérifié la structure transposée à PureBasic et elle me semble correcte.


Voici le programme

Code : Tout sélectionner


; Nécessite PortAudio installé (libportaudio.dylib accessible)

EnableExplicit

Enumeration
  #paNoError = 0
  
  #paNotInitialized = -10000
  #paUnanticipatedHostError
  #paInvalidChannelCount
  #paInvalidSampleRate
  #paInvalidDevice
  #paInvalidFlag
  #paSampleFormatNotSupported
  #paBadIODeviceCombination
  #paInsufficientMemory
  #paBufferTooBig
  #paBufferTooSmall
  #paNullCallback
  #paBadStreamPtr
  #paTimedOut
  #paInternalError
  #paDeviceUnavailable
  #paIncompatibleHostApiSpecificStreamInfo
  #paStreamIsStopped
  #paStreamIsNotStopped
  #paInputOverflowed
  #paOutputUnderflowed
  #paHostApiNotFound
  #paInvalidHostApi
  #paCanNotReadFromACallbackStream
  #paCanNotWriteToACallbackStream
  #paCanNotReadFromAnOutputOnlyStream
  #paCanNotWriteToAnInputOnlyStream
  #paIncompatibleStreamHostApi
  #paBadBufferPtr
EndEnumeration

ImportC "/opt/homebrew/Cellar/portaudio/19.7.0/lib/libportaudio.dylib"
  Pa_Initialize()
  Pa_Terminate()
  Pa_GetDeviceCount()
  Pa_GetDeviceInfo(device.l) ;typedef int PaDeviceIndex;
  Pa_GetHostApiInfo(hostApi.l) ;typedef int PaHostApiIndex;
  Pa_GetErrorText(errorCode.l) ; typedef int PaError;
EndImport

Debug "test d'erreur n° " + #paBadBufferPtr
; Obtenir le texte d'erreur pour une constante
Define *errorText = Pa_GetErrorText(#paBadBufferPtr)
Debug PeekS(*errorText, -1, #PB_Ascii)
;End

Structure PaDeviceInfo
  structVersion.l ;int structVersion
  name.i          ; ✅ pointeur vers chaîne ASCII (correct pour PeekS)
  hostApi.l       ;typedef int PaHostApiIndex;
  maxInputChannels.l ;int maxInputChannels
  maxOutputChannels.l;int	maxOutputChannels
  defaultLowInputLatency.d ; typedef double PaTime;
  defaultLowOutputLatency.d; typedef double PaTime;
  defaultHighInputLatency.d; typedef double PaTime;
  defaultHighOutputLatency.d ; typedef double PaTime;
  defaultSampleRate.d        ;double 	defaultSampleRate
EndStructure

Structure PaHostApiInfo
  structVersion.l;int 	structVersion
  type.i         ; typedef enum PaHostApiTypeId
  name.i         ;const char * name
  deviceCount.l  ;int deviceCount
  defaultInputDevice.l;typedef int PaDeviceIndex;
  defaultOutputDevice.l;typedef int PaDeviceIndex;
EndStructure

Define.i  err, numDevices, i
Define *deviceInfo.PaDeviceInfo
Define *hostApiInfo.PaHostApiInfo

err = Pa_Initialize()
If err <> 0
  MessageRequester("Erreur", "Erreur lors de l'initialisation : " + PeekS(Pa_GetErrorText(err), -1, #PB_Ascii))
  End
EndIf

numDevices = Pa_GetDeviceCount()
If numDevices < 0
  MessageRequester("Erreur", "Erreur lors de la récupération des périphériques : " + PeekS(Pa_GetErrorText(numDevices), -1, #PB_Ascii))
  Pa_Terminate()
  End
EndIf

Debug "Nombre de périphériques audio trouvés : " + Str(numDevices)
Debug ""

Procedure DebugMemory(*addr, size.l)
  Debug Str(size.l) + "  "
  Protected i, hex$, ascii$, byte.b, N.i
  N = 16
  For i = 0 To size - 1
    If i % N = 0
      If i > 0
        ;Debug " i : " + Str(i)
        Debug hex$ + "  " + ascii$
      EndIf
      hex$ = RSet(Hex(*addr + i), 12, "0") + " : "; écrire sur 12 et remplir de 0 à gauche
      ascii$ = ""  
    EndIf
    
    byte = PeekB(*addr + i)
    hex$ + RSet(Hex(byte & $FF), 2, "0") + " "
    
    If byte >= 32 And byte <= 126
      ascii$ + Chr(byte)
    Else
      ascii$ + "."
    EndIf
  Next
  
  If size > 0
    Debug "fin"
    Debug hex$ + "  " + ascii$
  EndIf
  
EndProcedure

For i = 0 To numDevices - 1
  *deviceInfo.PaDeviceInfo = Pa_GetDeviceInfo(i)
  If *deviceInfo = #Null
    Debug "Erreur: deviceInfo null pour l'appareil " + Str(i)
    Continue
  EndIf
  ; Vérification supplémentaire pour le nom du périphérique
  If *deviceInfo\name = #Null
    Debug "Périphérique " + Str(i) + " : [Nom non disponible]"
  Else
    Debug "Périphérique " + Str(i) + " : " + PeekS(*deviceInfo\name, -1, #PB_Ascii)
  EndIf
  
  ; Debug de la structure complète
  ;Debug "=== Dump mémoire deviceInfo ==="
  ;DebugMemory(*deviceInfo, SizeOf(PaDeviceInfo))
Next


Pa_Terminate()


Re: bibliothèque portaudio "accès mémoire invalide"

Publié : mar. 17/juin/2025 2:33
par SPH
det_uio a écrit : lun. 16/juin/2025 23:59 Pour montrer du code, utilise les bonnes balises (il y a meme mieux que les [ batise ] : les [ balise-pb ]
=>

Code : Tout sélectionner

; Nécessite PortAudio installé (libportaudio.dylib accessible) <==== je l'ai pas esssayé, ca m'a refroidi

EnableExplicit

Enumeration
  #paNoError = 0
  
  #paNotInitialized = -10000
  #paUnanticipatedHostError
  #paInvalidChannelCount
  #paInvalidSampleRate
  #paInvalidDevice
  #paInvalidFlag
  #paSampleFormatNotSupported
  #paBadIODeviceCombination
  #paInsufficientMemory
  #paBufferTooBig
  #paBufferTooSmall
  #paNullCallback
  #paBadStreamPtr
  #paTimedOut
  #paInternalError
  #paDeviceUnavailable
  #paIncompatibleHostApiSpecificStreamInfo
  #paStreamIsStopped
  #paStreamIsNotStopped
  #paInputOverflowed
  #paOutputUnderflowed
  #paHostApiNotFound
  #paInvalidHostApi
  #paCanNotReadFromACallbackStream
  #paCanNotWriteToACallbackStream
  #paCanNotReadFromAnOutputOnlyStream
  #paCanNotWriteToAnInputOnlyStream
  #paIncompatibleStreamHostApi
  #paBadBufferPtr
EndEnumeration

ImportC "/opt/homebrew/Cellar/portaudio/19.7.0/lib/libportaudio.dylib"
  Pa_Initialize()
  Pa_Terminate()
  Pa_GetDeviceCount()
  Pa_GetDeviceInfo(device.l) ;typedef int PaDeviceIndex;
  Pa_GetHostApiInfo(hostApi.l) ;typedef int PaHostApiIndex;
  Pa_GetErrorText(errorCode.l) ; typedef int PaError;
EndImport

Debug "test d'erreur n° " + #paBadBufferPtr
; Obtenir le texte d'erreur pour une constante
Define *errorText = Pa_GetErrorText(#paBadBufferPtr)
Debug PeekS(*errorText, -1, #PB_Ascii)
;End

Structure PaDeviceInfo
  structVersion.l ;int structVersion
  name.i          ; ✅ pointeur vers chaîne ASCII (correct pour PeekS)
  hostApi.l       ;typedef int PaHostApiIndex;
  maxInputChannels.l ;int maxInputChannels
  maxOutputChannels.l;int	maxOutputChannels
  defaultLowInputLatency.d ; typedef double PaTime;
  defaultLowOutputLatency.d; typedef double PaTime;
  defaultHighInputLatency.d; typedef double PaTime;
  defaultHighOutputLatency.d ; typedef double PaTime;
  defaultSampleRate.d        ;double 	defaultSampleRate
EndStructure

Structure PaHostApiInfo
  structVersion.l;int 	structVersion
  type.i         ; typedef enum PaHostApiTypeId
  name.i         ;const char * name
  deviceCount.l  ;int deviceCount
  defaultInputDevice.l;typedef int PaDeviceIndex;
  defaultOutputDevice.l;typedef int PaDeviceIndex;
EndStructure

Define.i  err, numDevices, i
Define *deviceInfo.PaDeviceInfo
Define *hostApiInfo.PaHostApiInfo

err = Pa_Initialize()
If err <> 0
  MessageRequester("Erreur", "Erreur lors de l'initialisation : " + PeekS(Pa_GetErrorText(err), -1, #PB_Ascii))
  End
EndIf

numDevices = Pa_GetDeviceCount()
If numDevices < 0
  MessageRequester("Erreur", "Erreur lors de la récupération des périphériques : " + PeekS(Pa_GetErrorText(numDevices), -1, #PB_Ascii))
  Pa_Terminate()
  End
EndIf

Debug "Nombre de périphériques audio trouvés : " + Str(numDevices)
Debug ""

Procedure DebugMemory(*addr, size.l)
  Debug Str(size.l) + "  "
  Protected i, hex$, ascii$, byte.b, N.i
  N = 16
  For i = 0 To size - 1
    If i % N = 0
      If i > 0
        ;Debug " i : " + Str(i)
        Debug hex$ + "  " + ascii$
      EndIf
      hex$ = RSet(Hex(*addr + i), 12, "0") + " : "; écrire sur 12 et remplir de 0 à gauche
      ascii$ = ""  
    EndIf
    
    byte = PeekB(*addr + i)
    hex$ + RSet(Hex(byte & $FF), 2, "0") + " "
    
    If byte >= 32 And byte <= 126
      ascii$ + Chr(byte)
    Else
      ascii$ + "."
    EndIf
  Next
  
  If size > 0
    Debug "fin"
    Debug hex$ + "  " + ascii$
  EndIf
  
EndProcedure

For i = 0 To numDevices - 1
  *deviceInfo.PaDeviceInfo = Pa_GetDeviceInfo(i)
  If *deviceInfo = #Null
    Debug "Erreur: deviceInfo null pour l'appareil " + Str(i)
    Continue
  EndIf
  ; Vérification supplémentaire pour le nom du périphérique
  If *deviceInfo\name = #Null
    Debug "Périphérique " + Str(i) + " : [Nom non disponible]"
  Else
    Debug "Périphérique " + Str(i) + " : " + PeekS(*deviceInfo\name, -1, #PB_Ascii)
  EndIf
  
  ; Debug de la structure complète
  ;Debug "=== Dump mémoire deviceInfo ==="
  ;DebugMemory(*deviceInfo, SizeOf(PaDeviceInfo))
Next


Pa_Terminate()[/quote]

Re: bibliothèque portaudio "accès mémoire invalide"

Publié : mar. 17/juin/2025 6:02
par venom
Je pense que Name.i n'est pas bon essaie de remplacer par

Code : Tout sélectionner

.l en 32 bits, .q en 64 bits ou .Integer  
Une piste a exploiter







@++

Re: bibliothèque portaudio "accès mémoire invalide"

Publié : mar. 17/juin/2025 19:46
par det_uio
J’ai bien fait correspondre la taille des éléments de la structure PaDeviceInfo.
J’ai toujours la même erreur avec

Code : Tout sélectionner

Debug "Périphérique " + Str(i) + " : " + PeekS(*deviceInfo\name, -1, #PB_Ascii)
De même il m'affiche 0 pour le nombre d'entrée et de sortie.

Le code que j'ai modifié pour que la structure corresponde :

Code : Tout sélectionner

; Nécessite PortAudio installé (libportaudio.dylib accessible)

EnableExplicit

Enumeration
  #paNoError = 0
  
  #paNotInitialized = -10000
  #paUnanticipatedHostError
  #paInvalidChannelCount
  #paInvalidSampleRate
  #paInvalidDevice
  #paInvalidFlag
  #paSampleFormatNotSupported
  #paBadIODeviceCombination
  #paInsufficientMemory
  #paBufferTooBig
  #paBufferTooSmall
  #paNullCallback
  #paBadStreamPtr
  #paTimedOut
  #paInternalError
  #paDeviceUnavailable
  #paIncompatibleHostApiSpecificStreamInfo
  #paStreamIsStopped
  #paStreamIsNotStopped
  #paInputOverflowed
  #paOutputUnderflowed
  #paHostApiNotFound
  #paInvalidHostApi
  #paCanNotReadFromACallbackStream
  #paCanNotWriteToACallbackStream
  #paCanNotReadFromAnOutputOnlyStream
  #paCanNotWriteToAnInputOnlyStream
  #paIncompatibleStreamHostApi
  #paBadBufferPtr
EndEnumeration

ImportC "/opt/homebrew/Cellar/portaudio/19.7.0/lib/libportaudio.dylib"
  Pa_Initialize()
  Pa_Terminate()
  Pa_GetDeviceCount()
  Pa_GetDeviceInfo(device.l) ;typedef int PaDeviceIndex;
  Pa_GetHostApiInfo(hostApi.l) ;typedef int PaHostApiIndex;
  Pa_GetErrorText(errorCode.l) ; typedef int PaError;
EndImport


; https://www.portaudio.com/docs/v19-doxydocs/structPaDeviceInfo.html
; PaDeviceInfo Struct Reference
; int 	structVersion                 4 octets sur la machine
; const char * 	name                8 octets sur la machine
; PaHostApiIndex 	hostApi             4 octets sur la machine
; int 	maxInputChannels              4 octets sur la machine
; int 	maxOutputChannels             4 octets sur la machine
; PaTime 	defaultLowInputLatency    8 octets sur la machine   (typedef double PaTime;)
; PaTime 	defaultLowOutputLatency   8 octets sur la machine   (typedef double PaTime;)
; PaTime 	defaultHighInputLatency   8 octets sur la machine   (typedef double PaTime;)
; PaTime 	defaultHighOutputLatency  8 octets sur la machine   (typedef double PaTime;)
; double 	defaultSampleRate         8 octets sur la machine

Structure PaDeviceInfo
  structVersion.l               ; 4 bytes
  name.q                        ; 8 bytes (quad)
  hostApi.l                     ;4 bytes
  maxInputChannels.l            ;4 bytes
  maxOutputChannels.l           ;4 bytes
  defaultLowInputLatency.d      ; 8 bytes
  defaultLowOutputLatency.d     ; 8 bytes
  defaultHighInputLatency.d     ; 8 bytes
  defaultHighOutputLatency.d    ; 8 bytes
  defaultSampleRate.d           ; 8 bytes
EndStructure

Structure PaHostApiInfo
  structVersion.l;int 	structVersion
  type.i         ; typedef enum PaHostApiTypeId
  name.i         ;const char * name
  deviceCount.l  ;int deviceCount
  defaultInputDevice.l;typedef int PaDeviceIndex;
  defaultOutputDevice.l;typedef int PaDeviceIndex;
EndStructure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Déclaration de la fonction prenant une référence à PaDeviceInfo
Declare tailles_PaDeviceInfo(*PaDeviceInfo)

Define.i  err, numDevices, i
Define *deviceInfo.PaDeviceInfo
Define *hostApiInfo.PaHostApiInfo
Define *errorText = Pa_GetErrorText(#paBadBufferPtr)

Debug "test d'erreur n° " + #paBadBufferPtr
; Obtenir le texte d'erreur pour une constante
Debug PeekS(*errorText, -1, #PB_Ascii)
;End


err = Pa_Initialize()
If err <> 0
  MessageRequester("Erreur", "Erreur lors de l'initialisation : " + PeekS(Pa_GetErrorText(err), -1, #PB_Ascii))
  End
EndIf

numDevices = Pa_GetDeviceCount()
If numDevices < 0
  MessageRequester("Erreur", "Erreur lors de la récupération des périphériques : " + PeekS(Pa_GetErrorText(numDevices), -1, #PB_Ascii))
  Pa_Terminate()
  End
EndIf

Debug "Nombre de périphériques audio trouvés : " + Str(numDevices)
Debug ""


For i = 0 To numDevices - 1
  Debug "--- device #" + i + "---"
  *deviceInfo = Pa_GetDeviceInfo(i)
  If *deviceInfo = #Null
    Debug "Erreur: deviceInfo null pour l'appareil " + i
    Continue
  EndIf
  
  Debug "maxInputChannels : " + *deviceInfo\maxInputChannels
  Debug "maxOutputChannels : " + *deviceInfo\maxOutputChannels
  
  
  ; Vérification supplémentaire pour le nom du périphérique
  If *deviceInfo\name = #Null
    Debug "Périphérique " + i + " : [Nom non disponible]"
  Else
    Debug "Périphérique " + i + " : " + PeekS(*deviceInfo\name, -1, #PB_Ascii)
  EndIf
  
  ; Debug de la structure complète
  If i=0
    ;Debug "=== Dump mémoire deviceInfo ==="
    ;DebugMemory(*deviceInfo, SizeOf(PaDeviceInfo))
    tailles_PaDeviceInfo(*deviceInfo)
  EndIf
  
Next


Pa_Terminate()

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Procedure tailles_PaDeviceInfo(*p.PaDeviceInfo)
  Debug ""
  Debug "SizeOf(*DeviceInfo) = " + SizeOf(*p)
  Debug "SizeOf(*p\structVersion) = " + SizeOf(*p\structVersion)
EndProcedure


Re: bibliothèque portaudio "accès mémoire invalide"

Publié : jeu. 19/juin/2025 21:25
par det_uio
ça y est j'ai la solution:

Tout réside dans cette astuce :

Code : Tout sélectionner

  Define namePtr = PeekQ(*deviceInfo + 8) ; Lire le pointeur (64 bits sur Mac ARM)
  Debug "name : " + PeekS(namePtr, -1, #PB_UTF8)
On a d'abord une adresse et non pas directement la chaîne de caractère. Ensuite il faut lire la chaîne contenu à cette adresse.

C'est comme en C avec :

Code : Tout sélectionner

const char *real_name = *(const char **)((const char *)p + 8);
// Afficher la chaîne pointée
 printf("Nom réel depuis *(p+8) : %s\n", real_name);
Pourquoi le champ name commence à partir de 8 alors que c'est le 2ème champ après le 1er structVersion qui fait 4 octets ?

Parce que pour des optimisations de mémoire le compilateur, par défaut, veut que le pointeur "name" soit un multiple de 8.

Ainsi cette version fonctionne :

Code : Tout sélectionner

; Nécessite PortAudio installé (libportaudio.dylib accessible)

EnableExplicit

Enumeration
  #paNoError = 0
  
  #paNotInitialized = -10000
  #paUnanticipatedHostError
  #paInvalidChannelCount
  #paInvalidSampleRate
  #paInvalidDevice
  #paInvalidFlag
  #paSampleFormatNotSupported
  #paBadIODeviceCombination
  #paInsufficientMemory
  #paBufferTooBig
  #paBufferTooSmall
  #paNullCallback
  #paBadStreamPtr
  #paTimedOut
  #paInternalError
  #paDeviceUnavailable
  #paIncompatibleHostApiSpecificStreamInfo
  #paStreamIsStopped
  #paStreamIsNotStopped
  #paInputOverflowed
  #paOutputUnderflowed
  #paHostApiNotFound
  #paInvalidHostApi
  #paCanNotReadFromACallbackStream
  #paCanNotWriteToACallbackStream
  #paCanNotReadFromAnOutputOnlyStream
  #paCanNotWriteToAnInputOnlyStream
  #paIncompatibleStreamHostApi
  #paBadBufferPtr
EndEnumeration

PrototypeC.i Proto_Pa_Initialize()
PrototypeC.i Proto_Pa_Terminate()
PrototypeC.i Proto_Pa_GetDeviceCount()
PrototypeC.q Proto_Pa_GetDeviceInfo(device.i)         ; const PaDeviceInfo*
PrototypeC.q Proto_Pa_GetHostApiInfo(hostApi.i)       ; const PaHostApiInfo*
PrototypeC.q Proto_Pa_GetErrorText(errorCode.i)       ; const char*

Global paLib = OpenLibrary(#PB_Any, "/opt/homebrew/Cellar/portaudio/19.7.0/lib/libportaudio.dylib")
If paLib
  Global Pa_Initialize.Proto_Pa_Initialize = GetFunction(paLib, "Pa_Initialize")
  Global Pa_Terminate.Proto_Pa_Terminate = GetFunction(paLib, "Pa_Terminate")
  Global Pa_GetDeviceCount.Proto_Pa_GetDeviceCount = GetFunction(paLib, "Pa_GetDeviceCount")
  Global Pa_GetDeviceInfo.Proto_Pa_GetDeviceInfo = GetFunction(paLib, "Pa_GetDeviceInfo")
  Global Pa_GetHostApiInfo.Proto_Pa_GetHostApiInfo = GetFunction(paLib, "Pa_GetHostApiInfo")
  Global Pa_GetErrorText.Proto_Pa_GetErrorText = GetFunction(paLib, "Pa_GetErrorText")
  
  If Pa_Initialize = 0 : MessageRequester("Erreur", "Pa_Initialize introuvable") : End : EndIf
  If Pa_Terminate = 0 : MessageRequester("Erreur", "Pa_Terminate introuvable") : End : EndIf
  If Pa_GetDeviceCount = 0 : MessageRequester("Erreur", "Pa_GetDeviceCount introuvable") : End : EndIf
  If Pa_GetDeviceInfo = 0 : MessageRequester("Erreur", "Pa_GetDeviceInfo introuvable") : End : EndIf
  If Pa_GetHostApiInfo = 0 : MessageRequester("Erreur", "Pa_GetHostApiInfo introuvable") : End : EndIf
  If Pa_GetErrorText = 0 : MessageRequester("Erreur", "Pa_GetErrorText introuvable") : End : EndIf
EndIf

Define err = Pa_Initialize()
If err
  MessageRequester("Erreur", PeekS(Pa_GetErrorText(err), -1, #PB_Ascii))
  End
EndIf

Define errorText = Pa_GetErrorText(#paBadBufferPtr)
Debug PeekS(errorText, -1, #PB_Ascii)

Define *errorText = Pa_GetErrorText(#paBadBufferPtr)
Debug PeekS(*errorText, -1, #PB_Ascii)

Define numDevices = Pa_GetDeviceCount()
If numDevices < 0
  MessageRequester("Erreur", "Erreur lors de la récupération des périphériques : " + PeekS(Pa_GetErrorText(numDevices), -1, #PB_Ascii))
  Pa_Terminate()
  End
EndIf
Debug "Nombre de périphériques audio trouvés : " + numDevices

Define i;
For i = 0 To numDevices - 1
  Debug ""
  Debug "--- device #" + i + " ---"
  Define *deviceInfo = Pa_GetDeviceInfo(i)
  
  If *deviceInfo = #Null
    Debug "Erreur: deviceInfo null pour l'appareil " + i
    Continue
  EndIf
  Debug "Sizeof : "+Str(SizeOf(*deviceInfo))
  Debug "structVersion : " + Str(PeekL(*deviceInfo + 0))
;   Debug "name : " + PeekS(*deviceInfo + 8, -1, #PB_Ascii)
  
  Define namePtr = PeekQ(*deviceInfo + 8) ; Lire le pointeur (64 bits sur Mac ARM)
  Debug "name : " + PeekS(namePtr, -1, #PB_UTF8)
  
  Debug "hostApi : " + Str(PeekL(*deviceInfo + 16));4
  Debug "maxInputChannels : " + Str(PeekL(*deviceInfo + 20));4
  Debug "maxOutputChannels : " + Str(PeekL(*deviceInfo + 24));4
  Debug "defaultLowInputLatency : " + StrD(PeekD(*deviceInfo + 32));8
  Debug "defaultLowOutputLatency : " + StrD(PeekD(*deviceInfo + 40));8
  Debug "defaultHighInputLatency : " + StrD(PeekD(*deviceInfo + 48));8
  Debug "defaultHighOutputLatency : " + StrD(PeekD(*deviceInfo + 56));8
  Debug "defaultSampleRate : " + StrD(PeekD(*deviceInfo + 64));8
Next
  
Pa_Terminate()

Re: bibliothèque portaudio "accès mémoire invalide"

Publié : ven. 20/juin/2025 14:01
par det_uio
Une autre méthode:
  • directement déclarer la structure avec l'option #PB_Structure_AlignC pour que les adresses des champs de la structure correspondent bien car il s'agit de de la librairie portaudio en C. L'avantage est d'appeler directement les champs de la structure par leur nom.
  • ImportC

Code : Tout sélectionner

; Nécessite PortAudio installé (libportaudio.dylib accessible)

EnableExplicit

Enumeration
  #paNoError = 0
  
  #paNotInitialized = -10000
  #paUnanticipatedHostError
  #paInvalidChannelCount
  #paInvalidSampleRate
  #paInvalidDevice
  #paInvalidFlag
  #paSampleFormatNotSupported
  #paBadIODeviceCombination
  #paInsufficientMemory
  #paBufferTooBig
  #paBufferTooSmall
  #paNullCallback
  #paBadStreamPtr
  #paTimedOut
  #paInternalError
  #paDeviceUnavailable
  #paIncompatibleHostApiSpecificStreamInfo
  #paStreamIsStopped
  #paStreamIsNotStopped
  #paInputOverflowed
  #paOutputUnderflowed
  #paHostApiNotFound
  #paInvalidHostApi
  #paCanNotReadFromACallbackStream
  #paCanNotWriteToACallbackStream
  #paCanNotReadFromAnOutputOnlyStream
  #paCanNotWriteToAnInputOnlyStream
  #paIncompatibleStreamHostApi
  #paBadBufferPtr
EndEnumeration

ImportC "/opt/homebrew/Cellar/portaudio/19.7.0/lib/libportaudio.dylib"
  Pa_Initialize()
  Pa_Terminate()
  Pa_GetDeviceCount()
  Pa_GetDeviceInfo(i) ;const PaDeviceInfo * Pa_GetDeviceInfo (PaDeviceIndex device)
  Pa_GetHostApiInfo(q);const PaHostApiInfo * Pa_GetHostApiInfo (PaHostApiIndex hostApi)
  Pa_GetErrorText(i)  ;const char * Pa_GetErrorText (PaError errorCode)
EndImport


Define err = Pa_Initialize()
If err
  MessageRequester("Erreur", PeekS(Pa_GetErrorText(err), -1, #PB_Ascii))
  End
EndIf

Structure PaDeviceInfo Align #PB_Structure_AlignC
  structVersion.l               ; 4 bytes
  name.q                        ; 8 bytes
  hostApi.l                     ;4 bytes
  maxInputChannels.l            ;4 bytes
  maxOutputChannels.l           ;4 bytes
  defaultLowInputLatency.d      ; 8 bytes
  defaultLowOutputLatency.d     ; 8 bytes
  defaultHighInputLatency.d     ; 8 bytes
  defaultHighOutputLatency.d    ; 8 bytes
  defaultSampleRate.d           ; 8 bytes
EndStructure

Debug ""

Define *info.PaDeviceInfo = Pa_GetDeviceInfo(0)
If *info
  Debug "Size of PaDeviceInfo: " + Str(SizeOf(PaDeviceInfo)) + " bytes"
  Debug "Offset of structVersion.l: " + Str(@*info\structVersion - *info)
  Debug "Offset of name.q: " + Str(@*info\name - *info)
  Debug "Offset of hostApi.l: " + Str(@*info\hostApi - *info)
  Debug "Offset of maxInputChannels.l: " + Str(@*info\maxInputChannels - *info)
  Debug "Offset of maxOutputChannels.l: " + Str(@*info\maxOutputChannels - *info)
  Debug "Offset of defaultLowInputLatency.d: " + Str(@*info\defaultLowInputLatency - *info)
  Debug "Offset of defaultLowOutputLatency.d: " + Str(@*info\defaultLowOutputLatency - *info)
  Debug "Offset of defaultHighInputLatency.d: " + Str(@*info\defaultHighInputLatency - *info)
  Debug "Offset of defaultHighOutputLatency.d: " + Str(@*info\defaultHighOutputLatency - *info)
  Debug "Offset of defaultSampleRate.d: " + Str(@*info\defaultSampleRate - *info)
  
  Debug ""
  
  Debug "structVersion : " + Str(*info\structVersion)
  Debug "name : " + PeekS(*info\name, -1, #PB_UTF8)
  Debug "hostApi : " + Str(*info\hostApi)
  Debug "maxInputChannels : " + Str(*info\maxInputChannels)
  Debug "maxOutputChannels : " + Str(PeekL(*info + 24))
  Debug "defaultLowInputLatency : " + StrD(*info\maxOutputChannels)
  Debug "defaultLowOutputLatency : " + StrD(*info\defaultLowOutputLatency)
  Debug "defaultHighInputLatency : " + StrD(*info\defaultHighInputLatency)
  Debug "defaultHighOutputLatency : " + StrD(*info\defaultHighOutputLatency)
  Debug "defaultSampleRate : " + StrD(*info\defaultSampleRate)
Else
  Debug "Allocation failed"
EndIf


Procedure PrintBytes(*ptr, size)
  Protected i
  Protected line.s = ""
  For i = 0 To size - 1
    line + RSet(Hex(PeekB(*ptr + i) & $FF), 2, "0") + " "
  Next i
  Debug Trim(line) ; Un seul Debug avec la ligne complète
EndProcedure


Pa_Terminate()