| |
|
|
Georg Hovenbitzer | Hallo zusammen,
ich habe folgendes Problem: Die Funktion AUDIOGetDuration liefert als Rückgabewert einen FLOAT Wert. Diesen bekomme ich einfach nicht gefasst, bei mir wird meistens die Biterate angezeigt. Der Programmierer der DLL Stefan Töngi war so freundlich und hat ein paar Test durchgeführt und schrieb dann.
Hi,
habe jetzt nochmal im Debug-Mode dein Beispielprojekt laufen lassen und die DLL-Funktionen werden korrekt aufgerufen. Auch die Rückgabewerte zu Profan sind korrekt. Anscheinend musst du noch explizit die Rückgabewerte angeben, denn bei den anderen korrekten Aufrufen werden überall LONG-Variablen verwendet, nur bei der Duration wird ein FLOAT zurückgegeben. Vielleicht wird da intern was falsch interpretiert. Schau mal im Profan Forum nach DLL und FLOAT, da findest du bestimmt was passendes...
Vielleicht könnt ihr mir helfen. (ich bin mir da eigentlich sehr sicher )
Ach ja, die DLL bekommt ihr unter www.audiogenie.de KompilierenMarkierenSeparierenDef AUDIOAnalyzeFile(1) !AudioGenie2.dll,AUDIOAnalyzeFile
Def AUDIOGetDuration(0) !AudioGenie2.dll,AUDIOGetDuration
Def AUDIOGetBitrate(0) !AudioGenie2.dll,AUDIOGetBitrate
Def AUDIOGetFileSize(0) !AudioGenie2.dll,AUDIOGetFileSize
Def MultiByteToWideChar(6) !KERNEL32.DLL,MultiByteToWideChar
Proc ToWide
Parameters Original$
Var L& = @Len(Original$)
Var Ziel$ = @Space$((L& * 2))
MultiByteToWideChar($0,$1,@Addr(Original$),L&,@Addr(Ziel$),(L& * 2))
Return Ziel$
EndProc
Proc _AUDIOAnalyzeFile
Parameters Pfad$
Pfad$ = ToWide(Pfad$)
Return AUDIOAnalyzeFile(@Addr(Pfad$))
EndProc
Proc _AUDIOGetDuration
Declare Ret#
Dim Ret#,8
Float Ret#,0 = AUDIOGetDuration()
Var Ret! = Float(Ret#,0)
Dispose Ret#
Return Ret!
EndProc
Proc _AUDIOGetBitrate
Return AUDIOGetBitrate()
EndProc
Proc _AUDIOGetFileSize
Return AUDIOGetFileSize()
EndProc
Declare ID3DLL&, Ende&, File$
Window 100,100-800,600
ID3DLL& = @UseDLL(AudioGenie2.dll)
WhileNot Ende& = 1
WaitInput
If %Key = 13
File$ =
File$ = @LoadFile$(ÖFFNE,*.mp3)
Cls
Print Gültige MP3 Datei = ,_AUDIOAnalyzeFile(File$)
Print
Print Duration = ,_AUDIOGetDuration()
Print
Print Bitrate = ,_AUDIOGetBitrate()
Print
Print FileSize = ,_AUDIOGetFileSize()
ElseIf %Key = 2
Ende& = 1
EndIf
EndWhile
FreeDLL ID3DLL&
End
|
|
|
| Viele Grüsse, Georg Hovenbitzer(Windows XP Pro, XProfan 11.2, Profan2Cpp 1.6a) | 24.06.2008 ▲ |
|
|
|
|
Dieter Zornow | Ich habe mal deinen Code ausprobiert und ein bischen experimentiert, da ich damals als Stefan Töngi die erste Version, hieß damals noch MP3Reader.dll herausbrachte , viel damit gemacht habe.
Das Ergebnis war aber immer das gleiche, ich bekam auch immer die Biterate angezeigt, habe das bei MP3 ´s mit verschieden Biteraten ausprobiert. Ich denke hier ist entweder bei Profan oder in der Dll etwas faul. Es ist aber schon seltsam, dass immer exakt die Biterate zurückkommt. Ich denke, dass die Dll bereits beim analysieren alle erkannte Werte im Speicher hinterlegt und vielleicht den Wert aus dem falschen Bereich zurückgibt. Dürfte aber nicht so sein, da sich dann schon bestimmt viele User gemeldet hätten.
Das mit dem Float-Bereich kannst du dir wahrscheinlich sparen. Eine einfache Float-Variable liefert den gleichen Wert.
Gruss
Dieter |
|
|
| Er ist ein Mann wie ein Baum. Sie nennen ihn Bonsai., Win 7 32 bit und Win 7 64 bit, mit XProfan X2 | 24.06.2008 ▲ |
|
|
|
|
| |
|
| |
|
|
|
RGH | Hallo!
Gibt die DLL einen 64- oder einen 32-Bit-Fließkommawert zurück?
Wenn es ein 64-Bit-Fließkommawert ist, wird es mit XProfan nicht gehen. Ist es ein 32-Bit-Wert, was wahrscheinlicher ist, kannst Du ihn zunächst in einem Longint speichern (= 32 Bit) und dann mit der Funktion @Float() in einen Fließkommawert XProfanscher Prägung (Double = 64 Bit) umwandeln.
Die Idee mit der Bereichsvariablen würde dann funktionieren, wenn nicht der Wert selbst, sondern dessen Adresse (Zeiger) zurückgegeben würde. Ein Verfahren, das zwar auch häufig anzutreffen ist, aber vermutlich nicht in diesem Fall.
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 24.06.2008 ▲ |
|
|
|
|
Georg Hovenbitzer | Hallo zusammnen,
vielen Dank für die Test und Tips.
@If Der Screenshot hängt an, es kommen dreimal die gleichen Werte raus.
@Roland Ich hoffe, ich habe deine Ausführungen richtig umgesetzt. Hierbei kommt es immer zu einer Schutzverletzung beim Versuch der Umwandlung in einen Fließkommawert. Ich habe beim Entwickler der DLL mal angefragt ob ein 64Bit oder 32Bit Wert zurück gegeben wird. KompilierenMarkierenSeparierenDef AUDIOAnalyzeFile(1) !AudioGenie2.dll,AUDIOAnalyzeFile
Def AUDIOGetDuration(0) !AudioGenie2.dll,AUDIOGetDuration
Def MultiByteToWideChar(6) !KERNEL32.DLL,MultiByteToWideChar
Proc ToWide
Parameters Original$
Var L& = @Len(Original$)
Var Ziel$ = @Space$((L& * 2))
MultiByteToWideChar($0,$1,@Addr(Original$),L&,@Addr(Ziel$),(L& * 2))
Return Ziel$
EndProc
Proc _AUDIOAnalyzeFile
Parameters Pfad$
Pfad$ = ToWide(Pfad$)
Return AUDIOAnalyzeFile(@Addr(Pfad$))
EndProc
Proc _AUDIOGetDuration
Declare Ret#
Dim Ret#,8
Float Ret#,0 = AUDIOGetDuration()
Var Ret! = @Float(Ret#,0)
Dispose Ret#
Return Ret!
EndProc
Proc _Roland
Var Ret& = AUDIOGetDuration()
Var Ret! = @Float(Ret&,0)
Return Ret!
EndProc
Declare ID3DLL&, Ende&, File$
Window 100,100-800,600
ID3DLL& = @UseDLL(AudioGenie2.dll)
WhileNot Ende& = 1
WaitInput
If %Key = 13
File$ =
File$ = @LoadFile$(ÖFFNE,*.mp3)
Cls
Print Gültige MP3 Datei = ,_AUDIOAnalyzeFile(File$)
Print
Print Duration = ,_AUDIOGetDuration()
Print
Print Lösungsvorschlag = ,_Roland()
Print
ElseIf %Key = 2
Ende& = 1
EndIf
EndWhile
FreeDLL ID3DLL&
End
|
|
|
| Viele Grüsse, Georg Hovenbitzer(Windows XP Pro, XProfan 11.2, Profan2Cpp 1.6a) | 26.06.2008 ▲ |
|
|
|
|
| Wenn AUDIOGetDuration() tatsächlich Drei mal in Folge 192 ausgibt ist zumindest klar, dass hinter diesem Wert keine Duration zurückgeliefert wird, oder Position 0 mit 192 Bit gemeint ist. |
|
|
| |
|
|
|
Dieter Zornow | Ich habe mal deinen Code getestet, bei mir kommt gar nichts, stürzt beim Aufruf gleich ab. Ich habe mir mal den Delphi-Wrapper geladen, danach ist es in Delphi eine Single - Variable 4 bytes groß. Ich habe aber keine Ahnung wie das in Profan umzusetzen ist. Allgemein ist die Dll was die Ein - und Ausgabe betrift sehr schlecht dokumentiert, deshalb ist der Wrapper nützlich man sieht zumindest was erwartet wird z.B. Unicode |
|
|
| Er ist ein Mann wie ein Baum. Sie nennen ihn Bonsai., Win 7 32 bit und Win 7 64 bit, mit XProfan X2 | 26.06.2008 ▲ |
|
|
|
|
RGH | Georg Hovenbitzer
@Roland Ich hoffe, ich habe deine Ausführungen richtig umgesetzt.
Ähem ... Ja und Nein ... dfenn ich habe Dir die falsche Funktion genannt. Nicht @Float(), sondern @Double() war gemeint. Die macht aus einer 32-Bit-Fließkommazahl (gespeichert im Integer) eine 64-Bit-Fließkommazahl. Versuche also mal KompilierenMarkierenSeparieren Gruß Roland
(Da ich die DLL momentan nicht hier habe, kann ich es nicht sofort testen.) |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 26.06.2008 ▲ |
|
|
|
|
RGH | Nachtrag:
Ich habe jetzt die DLL bei mir installiert. Gemäß der auf der Homepage der DLL vorhandenen ausführlichen deutschen Dokumentation ( [...] ) müßte meine Lösung funktionieren. Tut sie aber nicht. Ist es möglich, dass nicht alle MP3 die Information über die Länge in der Form enthalten, die die DLL auswertet? Für wahrscheinlicher halte ich aber einen Fehler in der DLL, da definitiv immer die Bitrate ausgegeben wird. Hier mein kleines Testprogramm: KompilierenMarkierenSeparieren
Proc Str2WideChar
Wandelt den Ansi-String Ansi$ in einen WideChar-String um
Parameters Ansi$
Declare Wide$
WhileLoop 1, Len(Ansi$)
Wide$ = Wide$ + Substr$(Ansi$, &loop) + z
EndWhile
Return Wide$
EndProc
Proc WideCharAddr2Str
Ermittelt aus der Adresse eines WideChar-Strings buf&
den entsprechenden Ansi-String
Parameters buf&
Declare I%, Ansi$, WChar$
I% = 0
WChar$ = Char$(buf&, I%, 2)
While WChar$ <> zz
Ansi$ = Ansi$ + Char$(buf&, I%, 1)
Inc I%, 2
WChar$ = Char$(buf&, I%, 2)
EndWhile
Return Ansi$
EndProc
Declare File$
Declare Dll&
Declare Tmp&
Cls
File$ = Str2WideChar(Test.mp3)
Dll& = @ImportDLL(AudioGenie2.dll, My_)
Print Handle DLL = ,Dll&
Tmp& = My_GetAudioGenieVersion()
Print Version = + WideCharAddr2Str(Tmp&)
Tmp& = My_AUDIOAnalyzeFile(Addr(File$))
Print bei MP3 sollte 1 kommen = ,Tmp&
Tmp& = My_GetID3V1Album()
Print Album = + WideCharAddr2Str(Tmp&)
Tmp& = My_GetID3V1Artist()
Print Artist = + WideCharAddr2Str(Tmp&)
Tmp& = My_GetID3V1Title()
Print Title = + WideCharAddr2Str(Tmp&)
Tmp& = My_AUDIOGetFileSize(Tmp&)
Print Größe (Bytes) = + Str$(Tmp&)
Tmp& = My_AUDIOGetBitrate(Tmp&)
Print Bitrate = + Str$(Tmp&)
Tmp& = My_AUDIOGetSampleRate(Tmp&)
Print Samplerate = + Str$(Tmp&)
Tmp& = My_AUDIOGetChannels(Tmp&)
Print Kanäle = + Str$(Tmp&)
Tmp& = My_AUDIOGetDuration()
Print Dauer (Sekunden) = + Str$(Double(Tmp&))
Tmp& = My_AUDIOGetLastErrorNumber(Tmp&)
Print Letzter Fehler = + Str$(Tmp&)
WaitInput
FreeDLL Dll&
End
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 26.06.2008 ▲ |
|
|
|
|
| Die Dauer einer MP3 ist imho reine Berechnungssache, Anzahl Bits dividiert durch bits/s.
Auf [...] steht liefert die Spieldauer in Sekunden, ist damit die Gesamtspieldauer oder die aktuell-bereits-vergangene-Spieldauer gemeint? |
|
|
| |
|
|
|
RGH | iF
Die Dauer einer MP3 ist imho reine Berechnungssache, Anzahl Bits dividiert durch bits/s. Auf [...] steht liefert die Spieldauer in Sekunden, ist damit die Gesamtspieldauer oder die aktuell-bereits-vergangene-Spieldauer gemeint?
Selbst wenn es die gespielte Dauer in Sekunden wäre, dürfte beim nicht gestarteten Song nicht die Bitrate (als 32-Bit-Integer) im Ergebnis stehen, dass gemäß Doku eine 32-Bit-Single ist.
Sehr seltsam, das Ganze ...
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 26.06.2008 ▲ |
|
|
|
|
| RGH
Selbst wenn es die gespielte Dauer in Sekunden wäre, dürfte beim nicht gestarteten Song nicht die Bitrate (als 32-Bit-Integer) im Ergebnis stehen, dass gemäß Doku eine 32-Bit-Single ist.
Sehr seltsam, das Ganze ...
Gruß Roland
Ist doch klar, es wirkt als wäre hier aus einem Register gezogen was zuvor für Berechnungen nötig war - könnte also sein das es ein Folgefehler ist weil nicht genügend vom Stack abgeholt wird.
Mit ein wenig Inlineassembler bekommt man das bestimmt schnell heraus. (Frank? Könntest Du bitte mal... hab mein inlineasm grad abgeschossen...) *g* |
|
|
| |
|
|