unsigned DWORD
Einige hier verwenden die Bass Library.
Habe mir die Mühe gemacht meinen Code nochmals zu analysieren inklusive eingeschalteter Bereichs Prüfung. Das Problem ist folgendes. BASS_ChannelGetData und andere Funktionen verursachen ERangeError's (manchmal) weil hier DWord unsigned (LongWord 0 bis 4294967295.) verwendet wird. Treten also minus werte auf dann kracht es. Die Library von Bass verschickt aber mit seinem Archiv die API Definiert wie folgt.
Delphi-Quellcode:
function BASS_ChannelGetData(handle: DWORD; buffer: Pointer; length: DWORD): DWORD;
Zitat:
Also muss ich die Bereichsprüfung ausgeschaltet lassen oder gibt es vergleichbare signierte Data Typen für DWord? Wenn nicht ist diese Library ohne ausgeschalteter Bereichsprüfung bzw. ohne jedes einzelne Sample vorher auf negative werte zu analysieren nicht verwendbar mit Delphi. gruss |
AW: unsigned DWORD
?unsigned? DWORD... es gibt bei xWORD da 100% gar kein "signed"/"unsigned"!
Ein WORD ist ein "unsigned 16BIT-Wert" und ein "DWORD" ist ein "unsigned 32BIT-Wert" und ein "QWORD" ist ein "unsigned 64BIT-Wert"... in allen Programiersprachen und in allen OS und auf allen Plattformen vom 8Bit Microcontroler bis zur 64Bit ARM/Intel CPU Ein DWORD (unter 32Bit Delphi "cardinal") kann per Definition keinen ungültigen "Bereich" haben, da alle Werte von $00000000..$FFFFFFFF gültig und zugelassen sind. Das "zufällig" $FFFFFFFF in 32BitDelphi auch für "-1" beim "Integer-Typ"steht und der Compiler dadurch eventuell meint ein $FFFFFFFF Cardinal/DWORD sei "out of Range", ist ein FEHLER der Bereichsprüfung durch dem Compiler! -> mache ein Minimalbeispiel und eröffne im QC bei Emab/Idera einen Fall |
AW: unsigned DWORD
unsigned bedeutet meines Erachtens das die werte im Bereich zwischen 0.. xxx + liegen.
signed werte können aber im Bereich zwischen -1.. xxx + liegen. Oder warum denkst du das es sonst einen ERangeError mit dem Data Typ DWORD in Delphi gibt? Dieser liegt nun mal bekanntlich im Bereich von 0 bis 4294967295. Also nochmal vom Bass Forum.. Zitat:
http://docwiki.embarcadero.com/Libra...em.Types.DWORD Zitat:
DWORD is a 4-byte unsigned integer. oder DWORD ist unsigned ist gehüpft wie gesprungen.. Das kannst du für dich definieren wie du willst ändert aber nichts an der Tatsache. Zitat:
Wie gesagt es ist ein unsauberer Code wenn ich bedingt durch die Data Typen die Bereichsprüfung ausschalten muss. Ein gefrickel ohne gleichen. :evil: gruss |
AW: unsigned DWORD
Sorry das ist kein Gefrickel, das ist pure binäre Logik.
"Oder warum denkst du das es sonst einen ERangeError mit dem Data Typ DWORD in Delphi gibt?"... für negative "Integer" Werte oder Konstanten die man ohne Cast auf DWORD zuweist(obwohl die Typgröße im Speicher passt) und in 64BitDelphi macht es Sinn (z.B. unter Delphi64Bit ist es klar, das eine = $FFFFFFFFFFFFFFFF für eine z.B. "Integer:-1" Zuweisung einen Fehler bei der Bereichsprüfung wirft, denn $FFFFFFFFFFFFFFFF ist dann nunmal größer wie der maximale $FFFFFFFF im DWORD Typ) Sorry für die Faulheit alles in Hex zu schreiben, da es eh um das Verständnis der entsprechenden 2er Potenzen geht, ist es so sogar "klarer" worum es geht. (in dezimal erkenne ich den Zusammenhang auch immer nicht sofort, aber das Spiel mit den Nullen&Einsen kann man sich durchaus mal BitByBit zu Gemüte führen;) ) BASS nutzt bei seinen DLL Deglerationen die WindowsAPI und C konforme Variante, möglichst alles vorzeichenlos Sprachen portabel mit 100% fix bestimmten Typen zu definieren. BYTE = unsigned 8Bit 0..$FF WORD = unsigned 16Bit 0..$FFFF DWORD = unsigned 32Bit 0..$FFFFFFFF QWORD = unsigned 64Bit 0..$FFFFFFFFFFFFFFFF Mit signed Variablen mit wo möglich noch ala "Integer" variablem Wertebereich kann ich in eigenen Programmteilen leben, aber wenn es um externe Kopplungen geht sollte man wie BASS es macht sich an die üblichen Standards halten. Wenn was in Delphi nicht passt, liegt es oft nur an "schlecht" definierten/portierten Konstanten welche z.B. als "-1" deglariert sind und bei aktivierter Bereichsprüfung eben nicht für einen DWORD Parameter verwendet werden können. |
AW: unsigned DWORD
Zitat:
Zitat:
Selbst wenn die BASS-Funktion ein -1 zurückgibt, sollte ein Vergleich auf eine DWORD-Konstante mit dem Wert $FFFFFFFF das gewünschte Ergebnis bringen (für das Gegenteil hätte ich dann gerne ein konkretes Beispiel). Solange die anderen Rückgabewerte nicht über MaxInt liegen, sollte auch ein Cast auf Integer funktionieren. Eine simple Zuweisung eines DWORD auf einen Integer wird aber gelegentlich zu einem RangeError führen, aber das ist ja auch so gewollt. Es ist natürlich schlechter Stil, wenn eine Typdeklaration ein DWORD angibt, die Dokumentation dann aber von -1 spricht. Das ist aber eindeutig die Schuld der BASS-Library. Wobei auch Microsoft in der Windows-API gerne mal einen solchen Fehlgriff verbaut hat. |
AW: unsigned DWORD
Hallo,
warum nimmst du dann nicht einfach Integer statt DWORD? |
AW: unsigned DWORD
Mit gefrickel meine ich das wenn ich die Bereichsprüfung für Bass extra ausschalten muss.
Es hatte nichts mit deiner Person zu tun. ;) oder den Byte Werten an sich. Zitat:
Einfaches Beispiel. Mit Bereichsprüfung wirft diese Funktion einen ERangeError. Nicht bei normaler Behandlung aber wenn ich die Samples pushe über einen Equalizer.
Delphi-Quellcode:
function BASS_ChannelGetData(handle: DWORD; buffer: Pointer; length: DWORD): DWORD;
Delphi-Quellcode:
Wie du siehst ist das ne simple Sache destotrotz werden Fehler geworfen..
function BassDataAvailable: BOOL;
var BytesValid: DWORD; begin result := TRUE; BytesValid := BASS_ChannelGetData(gnAudioChannel, nil, BASS_DATA_AVAILABLE); //<< ERangeError if BytesValid = DW_ERROR then result := FALSE; end; Ich kann die Samples natürlich einzeln analysieren und anschließend BytesValid den Wert übergeben. Nur wo steckt der Sinn dahinter. Und dieser hier!
Delphi-Quellcode:
Ich muss hier die Samples separat vorher Analysieren um den Fehler zu beheben.
for C := 1 to 2 do
Inc(pInteger[C]); // WaveData von TWaveData über BASS_ChannelGetData
Delphi-Quellcode:
for C := 1 to 2 do
begin IntI := pInteger[C]; if (IntI > 32767) then IntI := 32767 else if (IntI < -32768) then IntI := -32768; pInteger[C] := IntI; end; gruss |
AW: unsigned DWORD
Anderes Beispiel.
Delphi-Quellcode:
function BassChannelGetLevel: DWORD;
begin result := 0; if gnAudioPause = FALSE then begin if gnAudioChannel <> 0 then result := BASS_ChannelGetLevel(gnAudioChannel); end; end; Zitat:
Zitat:
Code:
exception class : ERangeError
exception message : Fehler bei Bereichsprüfung. usw.. gruss |
AW: unsigned DWORD
Und wie ist
Delphi-Quellcode:
deklariert?
gnAudioChannel
|
AW: unsigned DWORD
Zitat:
Delphi-Quellcode:
Ich habe nichts davon hier irgendwas zu erzählen ;)
HSTREAM = DWORD; // sample stream handle
gnAudioChannel: HSTREAM; (Cardinal) Möchte nur das es funktioniert auch mit eingeschalteter Bereichsprüfung. Das es nicht geht sieht man ja. Bei diesen einfachen Beispielen kann man nichts falsch machen. Kann aber auch nichts an den Ergebnis ändern das von Bass geliefert wird. D2010.. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz