Entwickler-Ecke

Multimedia / Grafik - Problem mit FMod Initialisierung


Mike_C - Sa 17.05.03 14:18
Titel: Problem mit FMod Initialisierung
Hi,

ich hab ein Problem mit der FMod initialisierung. Ich bin grad dabei mir das Coden mit FMod zu vereinfachen und ein paar Komponenten zu schreiben. Eine soll die Aufgabe haben FMOD zu initialisieren. Allerdings funktioniert das nicht so wirklich.

bei diesem Code bekomme ich AccessViolations (ab besten ich poste mal die ganze Klasse)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
unit SCSoundCore;

{$WARN UNSAFE_TYPE OFF}

interface

uses
  FMOD, MODCONSTS, FMODERRORS, FMODDYN, FMODPRESETS, FMODTYPES,
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ComCtrls;



type
  TSCSoundCore = class(TComponent)
  private
    { Private declarations }
    FInitialized: Boolean;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create (AOwner: TComponent); override;
    destructor Destroy; override;

    procedure Initialize;
  published
    { Published declarations }
    property Initialized: Boolean Read FInitialized;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SoundCore', [TSCSoundCore]);
end;

constructor TSCSoundCore.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FInitialized := False;
end;

destructor TSCSoundCore.Destroy;
begin
  inherited;
end;

procedure TSCSoundCore.Initialize;
begin
{ Check version numbers }
  if FMOD_VERSION > FSOUND_GetVersion then   //<--- die Zeile scheint Probleme zu machen :-(
  begin
    Application.MessageBox(PChar(Format('API version %3.2f is newer than DLL version %3.2f', [FMOD_VERSION, FSOUND_GetVersion])), 'Version mismatch', MB_OK or MB_ICONERROR);
    Halt;
  end;

  { Initialize FSOUND }
  try
    if not FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND) then
      raise Exception.Create('FSOUND_SetOutput failed');
    if not FSOUND_SetDriver(0then
      raise Exception.Create('FSOUND_SetDriver failed');
    if not FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT) then
      raise Exception.Create('FSOUND_SetMixer failed');
    if not FSOUND_SetHWND(Application.MainForm.Handle) then
      raise Exception.Create('FSOUND_SetHWND failed');
  except
    fInitialized := False;
    Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Initialization', MB_OK or MB_ICONHAND);
    raise;
  end;

  if not FSOUND_Init(220501280then
  begin
    Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'FSOUND_Init', MB_OK or MB_ICONHAND);
    fInitialized := False;
    Halt;
  end;
end;

end.


Ist daran irgendwas False?


mimi - Sa 17.05.03 22:30

an welcher stelle kommt die Fehlermeldung ?
versuche es mal per ShowMessages herrauszufinden....


Mike_C - So 18.05.03 11:58

Das interessante daran ist, dass das Problem am EntryPoint der Prozedur zu liegen scheint. Darauf weist folgendes hin:



So what says RedZack?! Ich habe eche keine Ahnung, woran das liegen könnte. :?


mimi - So 18.05.03 13:16

lass doch einfach:

Delphi-Quelltext
1:
2:
3:
4:
5:
if FMOD_VERSION > FSOUND_GetVersion then   //<--- die Zeile scheint Probleme zu machen :-( 
  begin 
    Application.MessageBox(PChar(Format('API version %3.2f is newer than DLL version %3.2f', [FMOD_VERSION, FSOUND_GetVersion])), 'Version mismatch', MB_OK or MB_ICONERROR); 
    Halt; 
  end;

ist doch eh unwichtig, welche version genutzt wird... ich würde das mit der version andres lösen: du nimmst eine constante und schreibst dort die version hin mit der du das Programm\komponente geschrieben hast.

versuche mal ShowMessage(intTostr(FSound_Getversion)) zu machen....


Mike_C - So 18.05.03 13:43

auf den Gedanken bin ich auch schon gekommen, dann bekomme ich die Accessviolation aber bei den ganzen if not... raise Abfragen. Frag mich nicht warum, ich weiß es nicht.

edit:
FSOUND_GetVersion scheint bei mir kaputt zu sein, ich kann zumindest über ein:

Delphi-Quelltext
1:
ShowMessage(Format('FSOUND_Getversion liefert Version: %g',[FSOUND_GETVERSION]));                    

nicht die Version bekommen, sondern meine AccessViolation...
aber Warum bekomme ich die AV auch, wenn ich den Versionsteil weglasse?


mimi - So 18.05.03 14:18

dann lase doch mal:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
{ Initialize FSOUND } 
  try 
    if not FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND) then 
      raise Exception.Create('FSOUND_SetOutput failed'); 
    if not FSOUND_SetDriver(0then 
      raise Exception.Create('FSOUND_SetDriver failed'); 
    if not FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT) then 
      raise Exception.Create('FSOUND_SetMixer failed'); 
    if not FSOUND_SetHWND(Application.MainForm.Handle) then 
      raise Exception.Create('FSOUND_SetHWND failed'); 
  except 
    fInitialized := False; 
    Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Initialization', MB_OK or MB_ICONHAND); 
    raise
  end;

weg ist auch nicht wichtig;)


Mike_C - So 18.05.03 16:01

was brauche ich denn ganz konkret von der initialisierung?


Mike_C - So 18.05.03 16:17

Cool, jetzt geht's... Hat jemand eine Idee, warum es vorher nicht ging?


mimi - So 18.05.03 17:16

was hast du denn gemacht ?


Mike_C - So 18.05.03 18:16

das, was du mir empfohlen hast: den unwichtigen Kram raus zu nehmen.
mir ist aber nicht ganz klar, was der mit der AccessViolation zu tun hat


mimi - So 18.05.03 19:36

schreibt mal den unwichtigen kram hinter FSound_init ich wette dann geht es :) :lol:


tommie-lie - So 18.05.03 20:27

Nein, die Funktionen, die aufgerufen werden,s ind nur gültig, bevor Init aufgerufen wurde. Danach sind die gesamten Treiber bereits geladen und ein dynamischen "umladen" unterstützt FMod zur Zeit noch nicht.
Der Code stammt, wie ich sehe, aus dem testbed-Sample. Versuch' mal die fmod-spezifischen uses-Clauses so zu machen wie dort: FMODDYN, MODCONSTS und FMODPRESETS raus. Die werden durch die FMod-Unit bereits initialisiert und FModDyn ist für dynamisches Laden der FMOD-DLL zuständig, was du hier nicht tust. Das wird vermutlich eher klappen als mimis Vorschläge, denn die Sachen sind gar nicht unwichtig. Zwar ist es unnötig, Exceptions auszulösen, aber die Initialisierung auf einen bestimmten Treiber sollte man schon vornehmen, sonst wird der Standard genommen, was nicht unbedingt beabsichtigt ist.


P.S.: Demnächst bitte die Delphi-Tags für Delphi-Quellcodes benutzen. Danke!


Mike_C - Mo 19.05.03 10:08

thx tommie-lie. jetzt funktioniert die komponente auch mit der Treiberinitialisierung.