Page 1 of 1

win or Mac, this code crashes

Posted: Tue Aug 12, 2025 6:52 am
by det_uio
Maybe you are interesting to solve
viewtopic.php?t=87290
here the GitHub project :
https://github.com/AudioNiceMicroContro ... -show-play

Re: win or Mac, this code crashes

Posted: Tue Aug 12, 2025 9:19 am
by RASHAD
Can't test it ,it's a miss :)

Change ProcedureReturn 0 to ProcedureReturn 1
I hope it will be OK

Code: Select all

Procedure dessine(canva.i, x.l, Array moyennes.d(1)); 1 pOUR VECTEUR !!!
  StartDrawing(CanvasOutput(canva))
  Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF) ; efface en blanc
  For i = 0 To #w-1
    LineXY(i, #h, i, #h-moyennes(i), RGB(0, 152, 0))
  Next i
  
  ; tracer la barre de position
  For i = 0 To 5
    LineXY(x+i, #h, x+i, #h-30, RGB(0, 0, 0))
  Next i
  StopDrawing()
  ProcedureReturn 1
EndProcedure

Re: win or Mac, this code crashes

Posted: Tue Aug 12, 2025 9:31 am
by miso

Code: Select all

Procedure.i dessine(canva.i, x.l, Array moyennes.d(1)); 1 pOUR VECTEUR !!!
I also cant test. I'm not sure if specifying a procedure return type would help, I guess not.

Re: win or Mac, this code crashes

Posted: Tue Aug 12, 2025 2:50 pm
by infratec
Works here with Win10 x64 and PB 6.21 x64 and a copied wav file with name _.wav
No crash.

A gadget is .i and not .l

And use EnableExplicit.

Re: win or Mac, this code crashes

Posted: Tue Aug 12, 2025 5:38 pm
by TI-994A
det_uio wrote: Tue Aug 12, 2025 6:52 amhere the GitHub project :
https://github.com/AudioNiceMicroContro ... -show-play
Downloaded the project from GitHub, and it ran perfectly with a 10MB sample wave file without any issues.

PureBasic 6.12 LTS running on Windows 10 x64.

Image

Re: win or Mac, this code crashes

Posted: Wed Aug 13, 2025 2:15 pm
by det_uio
It seems to get that with F5 which is the using of debugger by default (in my case).
I have used enableExplicit and all variable takes 8 bytes (.I or .d).
WhaitEvent() is used to get more reactivity.
I have to test it on Windows 11.

Here's the code

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; sndfile ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EnableExplicit
; --- Constantes libsndfile ---
#SFM_READ = $10 ; Mode lecture pour sf_open (0x10)
#SFM_WRITE = $20
#SFM_RDWR = $30

#SEEK_SET = 0
#SEEK_CUR = 1
#SEEK_END = 2

; --- Importation des fonctions libsndfile ---
ImportC "libsndfile.1.0.37.dylib"
  sf_open(filename.p-utf8, mode.l, *sfinfo)
  ;   sf_open(filename.s, mode.l, *sfinfo)  ; filename.s = PureBasic String
  sf_strerror(*sndfile)
  sf_close(*sndfile)
  sf_read_float(*sndfile, *ptr_float, frames.q)
  sf_readf_float(*sndfile, *ptr_float, frames.q)
  sf_seek(*sndfile, pos.i, style.i);sf_count_t  sf_seek  (SNDFILE *sndfile, sf_count_t frames, int whence) ;
EndImport

; --- Structure SF_INFO de libsndfile ---
Structure SF_INFO Align #PB_Structure_AlignC
  frames.i       ; sf_count_t (nombre de frames) 8
  samplerate.l   ; int (fréquence d'échantillonnage) 4
  channels.l     ; int (nombre de canaux) 4
  format.l       ; int (format du fichier, ex: WAV, FLAC, etc.) 4
  sections.l     ; int (nombre de sections) 4
  seekable.l     ; int (indique si le fichier est seekable) 4
EndStructure

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; portaudio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ==== Constantes ====
#paContinue = 0
#SampleRate = 44100
#FramesPerBuffer = 64
#TwoPi = 2 * #PI
#paFloat32 = $1
#paInt16   = $8
#paComplete = 1


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 "libportaudio.2.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)
  Pa_StartStream(*stream)
  Pa_StopStream(*stream)
  Pa_CloseStream(*stream)
  Pa_IsStreamActive(*stream)
  
  ;   typedef unsigned long PaSampleFormat;
  ;   PaError Pa_OpenDefaultStream (PaStream **stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData)
  Pa_OpenDefaultStream(*stream, inputChannels, outputChannels.l, sampleFormat.q, sampleRate.d, framesPerBuffer.q, *callback, *userData)
  
  Pa_Sleep(ms)
EndImport

Structure PaDeviceInfo Align #PB_Structure_AlignC
  structVersion.l               ;4 bytes
  *name                         ; 8 bytes
  hostApi.l                     ;4 bytes. int
  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

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

#FRAMES_PER_BUFFER = 512

Structure PaData
  file.i         ; SNDFILE* (pointeur vers la structure SF_SNDFILE, un handle de fichier)
  info.SF_INFO   ; Informations sur le fichier audio
EndStructure

; === Callback audio ===
ProcedureC.l audio_callback(*inputBuffer, *outputBuffer, framesPerBuffer.q, *timeInfo, statusFlags.q, *userData)
  Protected *audioData.PaData = *userData
  Protected *audioOut.FLOAT = *outputBuffer
  Protected num_read.q
  Protected i.l, totalSamples.l, filtre.f, input.f
  
  totalSamples = framesPerBuffer * *audioData\info\channels
  
  num_read = sf_read_float(*audioData\file, *audioOut, totalSamples)
  
  ProcedureReturn #paContinue
EndProcedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; --- Déclaration des variables ---
Define audioData.PaData

Define filename.s = "/Users/uio/Music/1.wav" ; Chemin du fichier WAV

; --- Ouverture du fichier WAV ---
audioData\info\format = 0 ; Initialise le format à 0 comme requis par sf_open
audioData\file = sf_open(filename, #SFM_READ, @audioData\info) ; Passe l'adresse de la structure SF_INFO

; OpenConsole()

If audioData\file = 0
  ; Récupère le message d'erreur de libsndfile
  ; #Null est la constante PureBasic pour un pointeur nul, équivalent à NULL en C.
  Define *error_str.Ascii = sf_strerror(#Null)
  ;   PrintN("Erreur lors de l'ouverture du fichier WAV : " + PeekS(*error_str, -1, #PB_Ascii))
  Debug("Erreur lors de l'ouverture du fichier WAV : " + PeekS(*error_str, -1, #PB_Ascii))
  End
EndIf

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

Define nbreEchantillonCanalGauche = audioData\info\frames
#w = 1000
#h = 200
Define nbFrameParPixel = nbreEchantillonCanalGauche / #w
; Debug("nbFrameParPixel : " + Str(nbFrameParPixel))
Define nAlire = nbFrameParPixel*2; stéréo
Dim tamp.f(nAlire)
Dim moyennes.d(#w)
Define uneMoyenne.d, max.d
Define *p = @tamp(0)
Define i, k, m
k = sf_read_float(audioData\file, *p, nAlire); on a lu les 2 canaux gauches et droits
While k=nAlire
  ;     Debug Str(i)+"   "+Str(nAlire)+"   "+Str(k)
  uneMoyenne=0
  For m = 0 To nAlire - 1
    uneMoyenne + Abs(PeekF(*p + (m) * SizeOf(Float)))
  Next m
  uneMoyenne/nAlire
  moyennes(i)=uneMoyenne
  k = sf_read_float(audioData\file, *p, nAlire)
  i+1
Wend

; trouver le max
max=moyennes(0)
For i = 0 To #w-1
  If max < moyennes(i)
    max = moyennes(i)
  EndIf
Next i
;normaliser
For i = 0 To #w-1
  moyennes(i) / max
  moyennes(i) * #h
Next i



OpenWindow(0, 100, 100, #w, #h, "2D Drawing Test")

Global monCanva
monCanva = CanvasGadget(#PB_Any, 0, 0, DesktopScaledX(#w), DesktopScaledY(#h))

Debug "monCanva  : "+Str(monCanva) 

Procedure dessine(canva, x, Array moyennes.d(1)); 1 pOUR VECTEUR !!!
  StartDrawing(CanvasOutput(canva))
  Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF) ; efface en blanc
  Protected i
  For i = 0 To #w-1
    LineXY(i, #h, i, #h-moyennes(i), RGB(0, 152, 0))
  Next i
  
  ; tracer la barre de position
  For i = 0 To 5
    LineXY(x+i, #h, x+i, 0, RGB(0, 0, 0))
  Next i
  StopDrawing()
  ;   ProcedureReturn 0
EndProcedure

dessine(monCanva, 10, moyennes())

sf_seek(audioData\file, 0, #SEEK_SET);


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


If Pa_Initialize() <> 0
  MessageRequester("Erreur", "Erreur initialisation PortAudio")
  sf_close(audioData\file)
  End
EndIf

Define *stream

If Pa_OpenDefaultStream(@*stream, 0, audioData\info\channels, #paFloat32, audioData\info\samplerate, #FRAMES_PER_BUFFER, @audio_callback(), @audioData) <> 0
  MessageRequester("Erreur", "Erreur ouverture flux audio")
  Pa_Terminate()
  sf_close(audioData\file)
  End
EndIf

If Pa_StartStream(*stream) <> 0
  MessageRequester("Erreur", "Erreur démarrage flux")
  Pa_CloseStream(*stream)
  Pa_Terminate()
  sf_close(audioData\file)
  End
EndIf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Debug("Fichier WAV '" + GetFilePart(filename) + "' ouvert avec succès.")
; Debug("Fréquence d'échantillonnage : " + Str(audioData\info\samplerate) + " Hz")
; Debug("Canaux : " + Str(audioData\info\channels))
; Debug("Nombre total de frames : " + Str(audioData\info\frames))

; AddWindowTimer(0, 0, 10) ; Timeout = 10 ms

Define Event, pos, x, y, res
Define pourc.d

Global lastTime = ElapsedMilliseconds()
Repeat
  Event = WindowEvent()
  If Event
    ;   Debug Event
    Select Event  
      Case #PB_Event_Gadget
        Select EventGadget()
          Case monCanva
            If EventType() = #PB_EventType_LeftClick
              x = GetGadgetAttribute(monCanva, #PB_Canvas_MouseX)
              y = GetGadgetAttribute(monCanva, #PB_Canvas_MouseY)
              pourc = x / #w
              pourc * audioData\info\frames
              pos = Int(pourc)
              sf_seek(audioData\file, pos, #SEEK_SET)
              ; Debug pourc
              ; Debug "Clic sur gauche: X=" + Str(x) + " Y=" + Str(y)
            EndIf
            
        EndSelect
      Default
;         Debug "oh" 
    EndSelect 
  Else
    Delay(50)
;     Debug "ok"
    pos = sf_seek(audioData\file, 0, #SEEK_CUR);
    pourc = pos / audioData\info\frames * 1.0
    pos = Int(pourc*#w)
    
    dessine(monCanva, pos, moyennes())
    
  EndIf
Until Event = #PB_Event_CloseWindow  ; If the user has pressed on the window close button


; === Nettoyage ===
Pa_StopStream(*stream)
Pa_CloseStream(*stream)
Pa_Terminate()
sf_close(audioData\file)

; Debug("Fichier WAV fermé.")


; Else
;   MessageRequester("Erreur", "Impossible d'ouvrir la console.")

; CloseConsole()

End

Re: win or Mac, this code crashes

Posted: Wed Aug 13, 2025 2:40 pm
by Axolotl
......I have used enableExplicit and all variable takes 8 bytes (.I or .d). .....

Sorry, but this is not correct. .l is 4 byte and .i on 64bit or .q is 8 bytes.
BTW: The comments in your code are correct.