Seite 3 von 4

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 13.02.2018 19:27
von ccode_new
Hallo Omi,

wenn ich den Datei-String als UTF8 übergebe:

Code: Alles auswählen

If ( SDL_LoadWAV_(UTF8(datei), @wave, @daten, @len) <> #Null )
springt es trotzdem in den Else-Block.

-> SDL_GetError_() liefert dabei nur andere kryptische Zeichen.
z.B. Ein Fehler: Couldn't open Xææ

Anbei: Wenn ich als Unicode übergebe stürzt das Programm Kommentarlos ab.

Anbei 2: Debug PeekS(fname,-1,#PB_Ascii) liefert aber den korrekten String.

????? Kennt sich jemand aus ?

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 13.02.2018 22:28
von DarkSoul
Wir kapern jetzt DarkSouls thread völlig :roll:
Nicht schlimm, da ich das Problem in meinem Fall gelöst habe. :mrgreen:

Vielleicht schafft ihr das ja noch irgendwie, SDL unter PB zum Laufen zu bringen. :)

Das sieht mir in disem Fall sehr nach nem kaputten Zeiger aus, weil der Zeichensalat dort steht, wo eigentlich ein Dateiname stehen sollte.

Edit: Habe ihn ausfindig gemacht.

Code: Alles auswählen

; SDL_LoadWAV
; Load a WAVE file
Procedure SDL_LoadWAV_(*fname, *spec, *audio_buf, *audio_len )
  ProcedureReturn SDL_LoadWAV_RW_(SDL_RWFromFile_(*fname,[color=#FF0000]@[/color]"rb"), 1, *spec, *audio_buf, *audio_len)
EndProcedure
Das rote @ fehlt bei dir (bzw. jenes zwischen den ungeparsten [color]-tags, ich kriege das gerade nicht hervorgehoben :mrgreen: ).

Der zweite Parameter von SDL_RW_FromFile ist ein Zeiger auf einen String. du übergibst dort direkt einen String. Der Dateiname ist in UTF8 angelegt, daher ist UTF8() schon richtig. https://wiki.libsdl.org/SDL_RWFromFile.

Musst mit den Strings aufpassen, weil PB die standardmäßig by value und C standardmäßig by reference (const char*) übergibt. :)

Wenn du das anpasst, dann lädt er bei mir die Datei, Schmiet dafür allerdings in Zeile 830 in der .pbi ab. :D

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 00:07
von ccode_new
Hallo DarkSoul,

das mit dem @ vor "rb" bringt bei mir irgendwie trotzdem noch nichts.

?????

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 00:30
von DarkSoul
Oder war das doch der erste Parameter? Einer von den beiden war jedenfalls kein korrekter Pointer. Ich habe die Datei beim Testen überschrieben und komme jetzt nicht mehr soweit zurück, um nochmal nachzusehen.

Musst natürlich noch die Methode SDL_RWFromFile_() entsprechend anpassen (Hattest dort Pointer auf Pointer übergeben. Wenn du im Hauptprogramm Pointer übergibst, darfst du in den Methoden deiner Lib nicht nochmal das @ bei der Übergabe verwenden, weil sonst haste Pointer auf Pointer und das war bei einem der Parameter der Fall):

Code: Alles auswählen

; SDL_RWFromFile
Procedure SDL_RWFromFile_( *fname, *mode)
  ProcedureReturn CallCFunctionFast(GetFunction(0, "SDL_RWFromFile"), *fname, *mode)
EndProcedure
Also bei mir lädt die Datei zuverlässig. Wenn das bei dir nicht der Fall ist, hast du noch irgendwo einen anderen Fehler drin, der sich nur bei dir auswirkt. :wink:

Ansonsten: Weiß heißt "das mit dem @ vor "rb" bringt bei mir irgendwie trotzdem noch nichts." genau?

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 00:45
von ccode_new
@DarkSoul:

Ok, die Datei läd jetzt, aber es wird kein Sound abgespielt.

Irgendwo anders ist da noch der Wurm drin.

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 00:53
von DarkSoul
Mindestens an der Stelle, die ich bereits geschrieben habe:
Wenn du das anpasst, dann lädt er bei mir die Datei, Schmiert dafür allerdings in Zeile 830 in der .pbi ab. :D
:mrgreen:

Ich mache immer ein '*' vor Zeigernamen. Ist in PB zwar nur ein statischer Name und hat nicht die gleiche Funktionalität wie bei C, aber so sehe ich immer, dass es sich um solche handelt und dann komme ich da nicht durcheinander. :wink:

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 03:40
von edel
Hi!

Ich habe den Code mal etwas ueberarbeitet. Es funktioniert ohne die vermurkste "sdl.pbi" unter Windows, wie es mit Linux aussieht weiss ich nicht

Code: Alles auswählen

Structure SDL_Userdata
  *buffer
  pos.l
  len.l
EndStructure

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  
#SDL_INIT_AUDIO    = $10
#AUDIO_S16         = $8010
#SDL_MIX_MAXVOLUME = 128

Structure SDL_AudioSpec
  freq.l
  format.w
  channels.b
  silence.b
  samples.w
  padding.w
  size.l
  *callback
  *userdata
EndStructure

Structure SDL_AudioCVT
  needed.l
  src_format.w
  dst_format.w
  rate_incr.double
  *buf
  len.l
  len_cvt.l
  len_mult.l
  PB_Alignment.b[4]
  len_ratio.double
  *filters[10]
  filter_index.l
  PB_Alignment1.b[4]
EndStructure

Import "sdl.lib" ; Windows 64 -> "D:\PellesC\Bin\polib.exe" SDL.dll /MACHINE:X64 /out:sdl.lib
  SDL_Init_(mod) As "SDL_Init"
  SDL_MixAudio_(*dst, *src, len, volume) As "SDL_MixAudio"
  SDL_GetError_() As "SDL_GetError"
  SDL_OpenAudio_(*desired, *obtained) As "SDL_OpenAudio"
  SDL_Quit_() As "SDL_Quit"
  SDL_LoadWAV_RW_(src, freesrc, spec, audio_buf, audio_len) As "SDL_LoadWAV_RW"
  SDL_FreeWAV_(*buffer) As "SDL_FreeWAV" 
  SDL_RWFromFile_(fileName.p-ascii, mode.p-ascii) As "SDL_RWFromFile"
  SDL_FreeRW_(*context) As "SDL_FreeRW"
  SDL_ConvertAudio_(*cvt) As "SDL_ConvertAudio"
  SDL_PauseAudio_(state) As "SDL_PauseAudio"
  SDL_BuildAudioCVT_( cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate) As "SDL_BuildAudioCVT"
EndImport

CompilerEndIf

Procedure.s getWave()
  Protected fileName.s = GetTemporaryDirectory() + "LRMonoPhase4.wav"
  InitNetwork()
  ReceiveHTTPFile("http://www.kozco.com/tech/LRMonoPhase4.wav", fileName)
  ProcedureReturn fileName
EndProcedure

Procedure printSDLError()
  Debug "Error!"
  Debug  PeekS(SDL_GetError_(), -1, #PB_Ascii)  
EndProcedure

Procedure loadWave(fileName.s, *uData.SDL_Userdata)
  Protected *context = SDL_RWFromFile_(fileName, "rb")
  Protected wav_spec.SDL_AudioSpec
  Protected *wav_buffer
  Protected wav_len.l
  Protected cvt.SDL_AudioCVT

  If *context = 0 
    ProcedureReturn printSDLError()
  EndIf
    
  If SDL_LoadWAV_RW_(*context, 1, wav_spec, @*wav_buffer, @wav_len) = 0
    ProcedureReturn printSDLError()
  EndIf  
  
   If SDL_BuildAudioCVT_(@cvt, wav_spec\format, wav_spec\channels, wav_spec\freq, #AUDIO_S16, 2, 48000) < 0      
     SDL_FreeRW_(*context)
     ProcedureReturn printSDLError()
   EndIf
   
   cvt\len = wav_len
   cvt\buf = AllocateMemory(cvt\len * cvt\len_mult)
   CopyMemory(*wav_buffer, cvt\buf, cvt\len)
   
   If SDL_ConvertAudio_(cvt)
     SDL_FreeRW_(*context)
     ProcedureReturn printSDLError()     
   EndIf
   
   SDL_FreeWAV_(*wav_buffer)
   
   *uData\buffer = cvt\buf
   *uData\len = cvt\len_cvt   
   
EndProcedure

ProcedureC audioCB(*userdata.SDL_Userdata, *stream, len.l) 
  
  If *userdata\len < 1
    ProcedureReturn
  EndIf
  
  If len > *userdata\len
    len = *userdata\len
  EndIf
    
  SDL_MixAudio_(*stream, *userdata\buffer + *userdata\pos, len, #SDL_MIX_MAXVOLUME)  
  
  *userdata\pos + len
  *userdata\len - len
  
EndProcedure

Procedure main()
  Protected outFor.SDL_AudioSpec
  Protected uData.SDL_Userdata
  
  outFor\freq     = 48000
  outFor\format   = #AUDIO_S16
  outFor\channels = 2
  outFor\samples  = 4096
  outFor\callback = @audioCB()   
  outFor\userdata = uData
  
  If SDL_Init_(#SDL_INIT_AUDIO)  
    ProcedureReturn printSDLError()    
  EndIf
  
  If SDL_OpenAudio_(outFor, #Null) 
    ProcedureReturn printSDLError()    
  EndIf  
  
  loadWave(getWave(), uData)
  
  SDL_PauseAudio_(0)
  
  While uData\len > 0    
  Wend  
  
  SDL_Quit_()
EndProcedure:End main()

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 15:11
von DarkSoul
Deine Implementierung finde ich viel sauberer :allright: .

Funktioniert allerdings trotzdem nicht:
Error!
Unrecognized file type (not WAVE)
Es wird keine PCM-Wave-Datei akzeptiert. Ab Zeile 80 gibt's Probleme, die ich jetzt auf die Schnelle nicht finden konnte (außer, dass im Import-Block der Dateiname mit p-ascii deklariert ist, woran es aber nicht liegt.)

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 18:55
von ccode_new
@edel

Fetzt !!! Du bist der Held! :praise:

So funktioniert es jetzt unter Linux:

Code: Alles auswählen

ImportC "-lSDL"
  SDL_Init_(mod) As "SDL_Init"
  SDL_MixAudio_(*dst, *src, len, volume) As "SDL_MixAudio"
  SDL_GetError_() As "SDL_GetError"
  SDL_OpenAudio_(*desired, *obtained) As "SDL_OpenAudio"
  SDL_Quit_() As "SDL_Quit"
  SDL_LoadWAV_RW_(src, freesrc, spec, audio_buf, audio_len) As "SDL_LoadWAV_RW"
  SDL_FreeWAV_(*buffer) As "SDL_FreeWAV"
  SDL_RWFromFile_(fileName.p-ascii, mode.p-ascii) As "SDL_RWFromFile"
  SDL_FreeRW_(*context) As "SDL_FreeRW"
  SDL_ConvertAudio_(*cvt) As "SDL_ConvertAudio"
  SDL_PauseAudio_(state) As "SDL_PauseAudio"
  SDL_BuildAudioCVT_( cvt, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate) As "SDL_BuildAudioCVT"
EndImport

Structure SDL_Userdata
  *buffer
  pos.l
  len.l
EndStructure

Procedure printSDLError()
  Debug "Error!"
  Debug  PeekS(SDL_GetError_(), -1, #PB_Ascii) 
EndProcedure

Procedure loadWave(fileName.s, *uData.SDL_Userdata)
  Protected *context = SDL_RWFromFile_(fileName, "rb")
  Protected wav_spec.SDL_AudioSpec
  Protected *wav_buffer
  Protected wav_len.l
  Protected cvt.SDL_AudioCVT

  If *context = 0
    ProcedureReturn printSDLError()
  EndIf
   
  If SDL_LoadWAV_RW_(*context, 1, wav_spec, @*wav_buffer, @wav_len) = 0
    ProcedureReturn printSDLError()
  EndIf 
 
   If SDL_BuildAudioCVT_(@cvt, wav_spec\format, wav_spec\channels, wav_spec\freq, #AUDIO_S16, 2, 48000) < 0     
     SDL_FreeRW_(*context)
     ProcedureReturn printSDLError()
   EndIf
   
   cvt\len = wav_len
   cvt\buf = AllocateMemory(cvt\len * cvt\len_mult)
   CopyMemory(*wav_buffer, cvt\buf, cvt\len)
   
   If SDL_ConvertAudio_(cvt)
     SDL_FreeRW_(*context)
     ProcedureReturn printSDLError()     
   EndIf
   
   SDL_FreeWAV_(*wav_buffer)
   
   *uData\buffer = cvt\buf
   *uData\len = cvt\len_cvt   
   
EndProcedure

ProcedureC audioCB(*userdata.SDL_Userdata, *stream, len.l)
 
  If *userdata\len < 1
    ProcedureReturn
  EndIf
 
  If len > *userdata\len
    len = *userdata\len
  EndIf
   
  SDL_MixAudio_(*stream, *userdata\buffer + *userdata\pos, len, #SDL_MIX_MAXVOLUME) 
 
  *userdata\pos + len
  *userdata\len - len
 
EndProcedure

Procedure main()
  Protected outFor.SDL_AudioSpec
  Protected uData.SDL_Userdata
 
  outFor\freq     = 48000
  outFor\format   = #AUDIO_S16
  outFor\channels = 2
  outFor\samples  = 4096
  outFor\callback = @audioCB()   
  outFor\userdata = uData
 
  If SDL_Init_(#SDL_INIT_AUDIO) 
    ProcedureReturn printSDLError()   
  EndIf
 
  If SDL_OpenAudio_(outFor, #Null)
    ProcedureReturn printSDLError()   
  EndIf 
 
  loadWave("snd.wav", uData)
 
  SDL_PauseAudio_(0)
 
  While uData\len > 0   
  Wend 
 
  SDL_Quit_()
EndProcedure:End main()
:allright:

Re: Wie Struktur aus C-Lib in PB importieren

Verfasst: 14.02.2018 19:51
von Omi
Hi!

Ich hätte auch grad mal gemütlich begonnen aus Interesse zur Entbuggung den Code aufzuräumen und zu straffen, aber ...
Super gemacht, Edel und gut einge'Linux't, ccode_new :allright:
Getestet unter PB5.46/x32 mit Ascii UND Unicode.

Das einzige was mir noch aufgefallen ist, um fallweise 'Aussetzer' unter Linux zu vermeiden:
Für 'schrägere' Dateinnamen mit Sonderzeichen bitte noch folgenden Import ändern:

Code: Alles auswählen

;von
SDL_RWFromFile_(fileName.p-ascii, mode.p-ascii) As "SDL_RWFromFile"
;in
SDL_RWFromFile_(fileName.p-utf8, mode.p-ascii) As "SDL_RWFromFile"

Grüße Charly