Wie Struktur aus C-Lib in PB importieren

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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 ?
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag von ccode_new »

Hallo DarkSoul,

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

?????
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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?
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag von ccode_new »

@DarkSoul:

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

Irgendwo anders ist da noch der Wurm drin.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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:
Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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()
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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.)
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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:
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: Wie Struktur aus C-Lib in PB importieren

Beitrag 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
PureBasic Linux-API-Library: http://www.chabba.de
Antworten