FMODEX-include

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Hab heute... *aufuhrzeitschau* ...ähm... gestern einen alten Code von
FroggerProgger aus dem PureBoard-Archiv herausgekramt und ihn auf
FMODEx umgebaut.
Da wird man ja noch blöd von den ganzen Flags... :freak:

Naja, auf jeden Fall klappt der Code jetzt und somit stelle ich ihn jetzt hier
mal rein:

Code: Alles auswählen

;- >> Sinemouse 0.3
;- FMOD-callback-example by Froggerprogger (23.01.05)
;- modified by NTQ (02.02.07)

Declare.l Buffercallback(hStream.l, BufferPointer.l, length.l)
Global Samplerate.l
Global Bits.l
Global Channels.l
Global max_samplevalue.w
Global fq.l, mpos.POINT

Macro Quote
  "
EndMacro
Macro OK(a)
  Debug Quote#a#Quote
  Result = a
  If Result
    Debug FMOD_ErrorString(Result)
    End
  EndIf
EndMacro

Samplerate = 44100 : Bits = 16 : Channels = 2
max_samplevalue = (1 << (Bits - 1)) - 1

Init_FMOD()

OK(FMOD_System_Create(@*System))

exinfo.FMOD_CREATESOUNDEXINFO
With exinfo
  \cbSize = SizeOf(FMOD_CREATESOUNDEXINFO)
  \Numchannels = Channels                     ;Anzahl Kanäle (Stereo)
  \defaultfrequency = Samplerate              ;Die Samplerate (44100)
  \Format = #FMOD_SOUND_FORMAT_PCM16          ;Das Format (16 Bit)
  \length = Samplerate                        ;Die Länge des Samples (1 Sekunde)
  \decodebuffersize = Samplerate / 40         ;Die Anzahl an Samples pro Callback-Aufruf (25 ms)
  \pcmreadcallback = @Buffercallback()        ;Der Pointer zum Callback
EndWith

OK(FMOD_System_Init(*System, Channels, #FMOD_INIT_NORMAL, 0))

OK(FMOD_System_CreateSound(*System, 0, #FMOD_2D | #FMOD_OPENUSER | #FMOD_SOFTWARE | #FMOD_CREATESTREAM | #FMOD_LOOP_NORMAL, @exinfo, @*Sound))

OK(FMOD_System_PlaySound(*System, #FMOD_CHANNEL_FREE, *Sound, #False, @*channel))

hwnd = OpenWindow(1, 0, 0, 240, 20, "Sinemouse 0.2, modified by NTQ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(hwnd)
TextGadget(1, 0,0, 150, 20, "")
TextGadget(2, 150, 0, 20, 20, "=")
TextGadget(3, 170, 0, 70, 20, "", #PB_Text_Right)

Repeat
  SetGadgetText(1, "Mouseposition: " + Str(mpos\x) + ", " + Str(mpos\y))
  SetGadgetText(3, Str(fq) + " Hz")
  FMOD_System_Update(*System)
Until WaitWindowEvent(1) = #PB_Event_CloseWindow

OK(FMOD_Channel_Stop(*channel))
OK(FMOD_Sound_Release(*Sound))
OK(FMOD_System_Release(*System))

End

Procedure.l Buffercallback(*Sound, *BufferPointer, length.l)
  Static angle.f, signed_word.w, sample_act.l, sample_last.l
  sample_act = 0
  sample_last = length - 1
  bytes_per_sample = Bits >> 3 * Channels
  While sample_act < sample_last
    GetCursorPos_(mpos)
    fq = (mpos\y + mpos\x) * 2 + 90                                            ; -> so frequences from 90 Hz to ((screenwidth+screenheight)*2)+90 Hz
    angle + 2 * #PI * (fq / Samplerate)                                        ; -> increase radian measure for the 'complex pointer'
    If angle > 2 * #PI : angle - 2 * #PI : EndIf                              ; -> avoid big (+ inaccurate) floats
    signed_word = Int(max_samplevalue * Sin(angle))                            ; -> calculate the real (sine) part of the cp
    
    For offset = 0 To Channels -1                                             ; (ok, not really stereo, just 'multichannel-mono' ;-)
      PokeW(*BufferPointer + sample_act + Bits >> 3 * offset, signed_word)     ; -> poke the same actual value for each channel
    Next
    sample_act + bytes_per_sample                                              ; -> next sample
  Wend
  
  ProcedureReturn #FMOD_OK
EndProcedure
Wenn es knackst, dann muss in Zeile 39 der Buffer angepasst werden,
z.B. so:

Code: Alles auswählen

\decodebuffersize = Samplerate / 20 ;für 50 ms
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Beitrag von Rings »

ts-soft hat geschrieben:Includierte DLL ist bei FMODEX.dll nicht erlaubt. Siehe Lizensbestimmungen!
1. Who cares ?
2. Die DLL wird nie nach sichtbar, wird also nur durch reverse-engineering sichtbar , ist das denn Erlaubt ?
3. Bei nem freeware oder opensource-projekt iss sowas doch schwanz
4. Wer liest Lizensbestimmungen ?
5. Hat sowas in Deutschland überhaupt anwendung ?

ach ja,
..
10. Für kommerzielle Sachen iss das okay.


ich wollt ja nurmal hierum-trollen.... :)
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Beitrag von rolaf »

Inzwischen gibts übrigens Version 4.06.06 vom 30.01.07
:::: WIN 10 :: PB 5.73 :: (x64) ::::
Benutzeravatar
Froggerprogger
Badmin
Beiträge: 855
Registriert: 08.09.2004 20:02

Beitrag von Froggerprogger »

Whoops, hier sind ja einige neue Antworten hinzugekommen!

Mal rückwärts:
@Falo:
Ich habe die api-Dateien soeben verglichen. Sie sind exakt gleich geblieben, bis auf die Versionsnummer:
Die hat sich von #FMOD_VERSION = $40601 auf #FMOD_VERSION = $40606 geändert. (Habe diese Änderung raufgeladen).

Der alte Import ließe sich also ohne weiteres auch für 4.06.06 verwenden. Die api wird wohl bei fast allen Updates nur minimal bis gar nicht verändert. Ich habe mir gerade auch 4.07.03 beta angesehen, dort ändert sich wieder nur die Versionsnummer.

@Rings
Du solltest andere nicht zu illegalen Dingen aufwiegeln! :wink: Nein, ich denke auch, dass das völlig i.O. wäre.

@Nic
Der import war 'halbautomatisch'. Ich habe folgendes hingeschmierte Progrämmchen genutzt (welches die /api/vb/*.bas-Dateien verarbeitet) und dann noch einige Anpassungen am Output vorgenommen, z.B. die CreateSound-Funktionen, sowie in Structure FMOD_DSP_DESCRIPTION das name.s nach name.b[32] geändert, die fmod_errors handangepasst und nachher alles in eine Datei gegossen.

Interfaces wären sehr cool, vielleicht hast du ja Zeit und Lust, einen besseren und vielleicht sogar vollautomatischen Importer zu schreiben.

Hier der bisherige:

Code: Alles auswählen

EnableExplicit

Procedure Convert(vb.l, pb.l)
  Protected line.s, lastEmpty.l, pos.l, enumMode.l, i.l, tempS.s, endPos.l
  Protected functionName.s, parameters.s
  lastEmpty = #True
  enumMode = #False
  
  While Eof(vb) = #False
    line = ReadString(vb)
    If Asc(Trim(line)) = 39 Or LSet(Trim(line), 10) = "Attribute "
      Continue
    EndIf
    line = RTrim(line)
    
    line = ReplaceString(line, "Select Case ", "Select ")
    line = ReplaceString(line, "End Select", "EndSelect")
    line = ReplaceString(line, "Case Is = FMOD", "Case #FMOD")
    line = ReplaceString(line, "Case Is = ", "Case ")
    
    line = ReplaceString(line, "Public Type", "Structure")
    line = ReplaceString(line, "End Type", "EndStructure")
    
    line = ReplaceString(line, "Public Function ", "Procedure.s ")
    line = ReplaceString(line, "End Function", "EndProcedure")
    
    If FindString(line, "Public Enum", 1)
      line = ReplaceString(line, "Public Enum", "Enumeration ;")
      enumMode = #True
    EndIf
    If FindString(line, "End Enum", 1)
      line = ReplaceString(line, "End Enum", "EndEnumeration")
      enumMode = #False
    EndIf
    
    pos = FindString(line, "Public Const ", 1)
    If pos
      line = ReplaceString(line, "Public Const ", "#")
      line = ReplaceString(line, "FMOD_", "#FMOD_", 0, 4)
      line = ReplaceString(line, "As Long", "")
      line = ReplaceString(line, "As String", "")
      line = ReplaceString(line, "As Single", "")
      line = ReplaceString(line, "Or", "|")
    Else
      If FindString(line, "As", 1)
        For i=20 To 0 Step -1
          If FindString(line, Space(i) + "As", 1)
            line = ReplaceString(line, Space(i) + "As Long", ".l" + Space(i))
            line = ReplaceString(line, Space(i) + "As String", ".s" + Space(i))
            line = ReplaceString(line, Space(i) + "As Single", ".f" + Space(i))
            line = ReplaceString(line, Space(i) + "As Byte", ".b" + Space(i))
            line = ReplaceString(line, Space(i) + "As ", ".")
          EndIf
        Next
      EndIf
    EndIf
    
    pos = 1
    Repeat
      pos = FindString(line, ".FMOD_", pos)
      If pos
        endPos = FindString(line, ",", pos)
        If endPos = 0
          endPos = FindString(line, ")", pos)
        EndIf
        If endPos
          line = Mid(line, 1, pos-1) + ".l" + Mid(line, endPos, #MAXLONG)
        Else
          pos = 0
        EndIf
      EndIf
    Until pos = 0
    

    line = ReplaceString(line, " Data", " _data")
    line = ReplaceString(line, "&H", "$")
    pos = FindString(line, "'", 1)
    If pos
      line = Mid(line, 1, pos-1) + ";" + Mid(line, pos+1, #MAXLONG)
    EndIf
    
    If Right(line, 1) = "'"
      line = Mid(line, 1, Len(line)-1)
    EndIf
    
    If enumMode = #True And Left(Trim(line), 11) <> "Enumeration" And Trim(line) <> ""
      line = ReplaceString(line, "FMOD_", "#FMOD_", 0, 4)
    EndIf

    If FindString(line, "Public Declare Function ", 1)
      line = ReplaceString(line, "Public Declare Function ", "")
      line = ReplaceString(line, "ByVal ", "")
      line = ReplaceString(line, "ByRef ", "*")
      line = ReplaceString(line, " Lib " + Chr(34) + "fmodex.dll" + Chr(34), "")
      line = ReplaceString(line, " ,", ",")
      line = ReplaceString(line, " )", ")")
      
      pos = FindString(line, "(", 1)
      endPos = FindString(line, ")", pos)
      If FindString(line, " ", 1) > 0 And FindString(line, " ", 1) < pos
        functionName = Trim(Left(line, FindString(line, " ", 1)-1))
      Else
        functionName = Trim(Left(line, pos))
      EndIf
      parameters = Mid(line, pos+1, endPos-pos-1)
      
      If Right(Trim(line), 12) = ".FMOD_RESULT"
        line = ReplaceString(line, ".FMOD_RESULT", "")
        tempS = "Procedure.l " + line
        WriteStringN(pb, tempS)
        WriteStringN(pb, "    ProcedureReturn CallFunction(fmodLib, " + Chr(34) + functionName + Chr(34) + ", " + parameters + ")")
      Else
        WriteStringN(pb, tempS)
        WriteStringN(pb, "    CallFunction(fmodLib, " + Chr(34) + functionName + Chr(34) + ", " + parameters + ")")
        tempS = "Procedure " + line
      EndIf
      WriteStringN(pb, "EndProcedure")
      WriteStringN(pb, "")

    Else
      If lastEmpty = #False Or Trim(line) <> ""
        WriteStringN(pb, line)
      EndIf 
      
      If Trim(line) = ""
        lastEmpty = #True
      Else
        lastEmpty = #False
      EndIf
    EndIf
  Wend
EndProcedure

Define.l vb, pb

vb.l = OpenFile(#PB_Any, "fmod_dsp.bas") : pb.l = CreateFile(#PB_Any, "fmod_dsp.pb")
Convert(vb, pb)
CloseFile(vb) : CloseFile(pb)

vb.l = OpenFile(#PB_Any, "fmod_errors.bas") : pb.l = CreateFile(#PB_Any, "fmod_errors.pb")
Convert(vb, pb)
CloseFile(vb) : CloseFile(pb)

vb.l = OpenFile(#PB_Any, "fmodex.bas") : pb.l = CreateFile(#PB_Any, "fmodex.pb")
WriteStringN(pb, "Global fmodLib.l")
WriteStringN(pb, "Procedure Init_FMOD()")
WriteStringN(pb, "    fmodLib = OpenLibrary(#PB_Any, " + Chr(34) + "fmodex.dll" + Chr(34) + ")")
WriteStringN(pb, "    ProcedureReturn IsLibrary(fmodLib)")
WriteStringN(pb, "EndProcedure")
WriteStringN(pb, "")
Convert(vb, pb)
CloseFile(vb) : CloseFile(pb) 
; jaPBe Version=2.5.2.24
; Build=0
; FirstLine=0
; CursorPosition=0
; ExecutableFormat=Windows
; DontSaveDeclare
; EOF
!UD2
Benutzeravatar
tft
Beiträge: 650
Registriert: 08.09.2004 20:18
Computerausstattung: GFX 3060 Ti , i7 12700F , 32 GB Ram , 900 GB SSD , TV
Wohnort: Dachsen
Kontaktdaten:

Beitrag von tft »

Hallo ...

bei mir funktioniert die FModeEx garnicht. Diese Funktion FMOD_System_CreateStream(fmodsystem, @str, #FMOD_SOFTWARE, 0, @sound)
gibt in sound eine null zurück. Obwohl der Pfad existiert. Es wird auch keine Fehlermeldung ausgegeben. Die Zeile stammt aus dem Beispiel.

mfg TFT
TFT seid 1989 , Turgut Frank Temucin , CH-Dachsen/DE-Berlin/TR-Antalya
Mein Projekt (Driving School Evergarden)
Codes bei (GitHub) Videos von (YouTube)
Treffen via Discord: Einladung

PB 6.10 | W11 | i7 12700F | 32 GB Ram | RTX 3060 Ti | 60 Herz -TV FullHD
ARDUINO Freak | Sprecher | Game Dev. | Geschichten Erzähler :-)
Benutzeravatar
Froggerprogger
Badmin
Beiträge: 855
Registriert: 08.09.2004 20:02

Beitrag von Froggerprogger »

Checke doch mal die Rückgabewerte von Init_FMOD() (muss ungleich 0 sein), FMOD_System_Create(...) und FMOD_System_Init(...) (müssen beide gleich 0 sein).

Dort würde bspw. ein Fehler passieren, wenn die fmodex.dll nicht gefunden wird, oder die Soundkarte nicht zur Ausgabe geöffnet werden. Die FMOD-Hilfe liefert dann anhand der Fehlercodes (also falls 0) eine genauere Beschreibung des Fehlers.

Ansonsten könnte es ggf. noch sein, dass du Unicode-Strings in Deinem Programm nutzt, aber FMOD_Stream_Create erwartet einen einfachen ASCII-String. Ich weiß nicht, ob dies zu Problemen führt, aber möglich wäre es.
!UD2
Benutzeravatar
tft
Beiträge: 650
Registriert: 08.09.2004 20:18
Computerausstattung: GFX 3060 Ti , i7 12700F , 32 GB Ram , 900 GB SSD , TV
Wohnort: Dachsen
Kontaktdaten:

Beitrag von tft »

Hallo

also die rückgabewerte sind ok. Die Play Funktion erzeugt einen Fehler weil der Sound ohne fehlermeldung nicht geladen wird. Haste mal ein Beispiel das bei dir schon immer funktioniert hat. Mit Wav etc.
TFT seid 1989 , Turgut Frank Temucin , CH-Dachsen/DE-Berlin/TR-Antalya
Mein Projekt (Driving School Evergarden)
Codes bei (GitHub) Videos von (YouTube)
Treffen via Discord: Einladung

PB 6.10 | W11 | i7 12700F | 32 GB Ram | RTX 3060 Ti | 60 Herz -TV FullHD
ARDUINO Freak | Sprecher | Game Dev. | Geschichten Erzähler :-)
Benutzeravatar
Froggerprogger
Badmin
Beiträge: 855
Registriert: 08.09.2004 20:02

Beitrag von Froggerprogger »

Teste mal diesen Source:

Code: Alles auswählen

;- SimplePlay with fmodex-include

IncludeFile "fmodex.pb"

If Init_FMOD() = 0
  MessageRequester("Error", "Couldn't load fmodex.dll")
EndIf

If FMOD_System_Create(@fmodsystem)
  MessageRequester("Error", "Couldn't create fmod-system")
EndIf

If FMOD_System_Init(fmodsystem, 32, 0, 0)
  MessageRequester("Error", "Couldn't initialize fmod-system")
EndIf

str.s = GetClipboardText()
If FileSize(str) < 0
  str = ""
EndIf
str.s = OpenFileRequester("Choose a soundfile", str, "*.*|*.*", 0)

If str = ""
  End
Else
  SetClipboardText(str)
EndIf

If FMOD_System_CreateStream(fmodsystem, @str, #FMOD_SOFTWARE, 0, @sound)
  MessageRequester("Error", "Couldn't create stream for file " + str)
EndIf

If FMOD_System_PlaySound(fmodsystem, 0, sound, 0, @channel)
  MessageRequester("Error", "Couldn't play sound")
EndIf

MessageRequester("Information", "You should here now the selected sound until you press OK.")

FMOD_System_Release(fmodsystem)
mit irgendeiner Musikdatei, z.B. dieser hier:

http://www.2mal2mal.de/public/purebasic ... sAgoEx.mp3

Funzt bei mir ohne Probleme. Dabei liegt die fmodex.dll lediglich im Purebasic/Compilers-Verzeichnis.
!UD2
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag von a14xerus »

hab ich mal für irgendeinen hier im forum gemacht ;)

http://www.alexander-n.de/uploads/?id=1190222670

(mit spektralanalyse)
Benutzeravatar
tft
Beiträge: 650
Registriert: 08.09.2004 20:18
Computerausstattung: GFX 3060 Ti , i7 12700F , 32 GB Ram , 900 GB SSD , TV
Wohnort: Dachsen
Kontaktdaten:

Beitrag von tft »

Hallo ...

folgende fehlermeldung kommt

"Error", "Couldn't play sound"

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , CH-Dachsen/DE-Berlin/TR-Antalya
Mein Projekt (Driving School Evergarden)
Codes bei (GitHub) Videos von (YouTube)
Treffen via Discord: Einladung

PB 6.10 | W11 | i7 12700F | 32 GB Ram | RTX 3060 Ti | 60 Herz -TV FullHD
ARDUINO Freak | Sprecher | Game Dev. | Geschichten Erzähler :-)
Antworten