Informationen aus MP3-Dateien auslesen
Moderator: Moderatoren
-
- 1000 working lines a day
- Beiträge: 525
- Registriert: Mi, 01. Feb 2006 16:22
- Wohnort: 06618 Naumburg
Informationen aus MP3-Dateien auslesen
Hallo, vielleicht hat jemand einen Tipp für mich.
Ich möchte Informationen aus MP3-Dateien auslesen. Ich benötige die Spieldauer und die Sampling-Rate. Evtl. noch die Möglichkeit ID-Tags zu lesen oder zu ändern. Das MP3-Beispiel auf der Alaska-Website bringe ich leider nicht zum Laufen weil der angegebene Link für die mp3.dll nicht funktioniert. Auch mit anderen mp3.dll`s klappt nicht.
Ich möchte Informationen aus MP3-Dateien auslesen. Ich benötige die Spieldauer und die Sampling-Rate. Evtl. noch die Möglichkeit ID-Tags zu lesen oder zu ändern. Das MP3-Beispiel auf der Alaska-Website bringe ich leider nicht zum Laufen weil der angegebene Link für die mp3.dll nicht funktioniert. Auch mit anderen mp3.dll`s klappt nicht.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Hallo, Peter.
Diese MP3.DLL gibt's anscheinend nicht mehr als Freeware; ich bin eine Weile durch die spanischsprachigen Sites gestolpert und immer wieder auf einer PayPal-Site gelandet.
Aber MPEG/MP3 sind vergleichsweise simpel. MP3 mit ID-Tags basiert auf MP2. Beide Formatbeschreibungen findest Du u.a. hier:
http://audio.layer2.de/das_mp2format.php
http://audio.layer2.de/das_mp3format.php
Einfach byteweise auslesen.
Diese MP3.DLL gibt's anscheinend nicht mehr als Freeware; ich bin eine Weile durch die spanischsprachigen Sites gestolpert und immer wieder auf einer PayPal-Site gelandet.
Aber MPEG/MP3 sind vergleichsweise simpel. MP3 mit ID-Tags basiert auf MP2. Beide Formatbeschreibungen findest Du u.a. hier:
http://audio.layer2.de/das_mp2format.php
http://audio.layer2.de/das_mp3format.php
Einfach byteweise auslesen.
Herzlich,
Tom
Tom
-
- 1000 working lines a day
- Beiträge: 525
- Registriert: Mi, 01. Feb 2006 16:22
- Wohnort: 06618 Naumburg
klappt nicht so richtig
ja, klingt theoretisch ganz einfach - ich bekomms aber nicht gebacken.
Habe mir eine kleine Function geschrieben, um die Infos byteweise auszulesen und anzeigen zu lassen. Ich bekomme aber nichts angezeigt. Vielleicht findet einer den Fehler
Bin für jeden Hiwneis dankbar. Die Links waren super [/code]
Habe mir eine kleine Function geschrieben, um die Infos byteweise auszulesen und anzeigen zu lassen. Ich bekomme aber nichts angezeigt. Vielleicht findet einer den Fehler
Code: Alles auswählen
#include "fileio.ch"
proc say_header(cDatei)
LOCAL nHandle := 0, inhalt:=space(32)
//
nHandle := FOPEN(cDatei, FO_READ + FO_SHARED)
//
IF nHandle > 0
FREAD(nHandle, inhalt,32) //32 byte auslesen
ENDIF
//
FCLOSE(nHandle)
//
msgbox(inhalt)
//
return
Hallo Leute,
ich habe mal für einen Freund ein Tool geschrieben, daß den Titel, Interpret aus dem Dateiname in den ID3Tag schreibt.
Hier ohne Korrektur die Schreibroutine.
ich habe mal für einen Freund ein Tool geschrieben, daß den Titel, Interpret aus dem Dateiname in den ID3Tag schreibt.
Hier ohne Korrektur die Schreibroutine.
Code: Alles auswählen
********************
FUNCTION ID3PUT(cFZiel, Titel, Interpret, Album )
********************
LOCAL nWrite:=1, cT:="ID3"+chr(03)+chr(0)+chr(0)+chr(0)+chr(0)+chr(15)+"v", nNr, nH
LOCAL V1:="TAG", bV1:=.f., bV2:=.f., cBuffer:=space(127)
if nWrite >0
* ID3V2 wird an den Dateianfang gestellt
cT+="TIT2"+chr(0)+chr(0)+chr(0)+chr(len(Titel)+1)+chr(0)+chr(0)+chr(0)+Titel
cT+="TPE1"+chr(0)+chr(0)+chr(0)+chr(len(Interpret)+1)+chr(0)+chr(0)+chr(0)+Interpret
cT+="TALB"+chr(0)+chr(0)+chr(0)+chr(len(Album)+1)+chr(0)+chr(0)+chr(0)+Album
cT+= Replicate(chr(0), 100)
* ID3V1 kommt ans Dateiende
V1+=padr(Titel , 30, chr(0))
V1+=padr(Interpret, 30, chr(0))
V1+=padr(Album , 30, chr(0))
V1+=repl(chr(0), 34)+chr(255)
if ( nH := FOpen(cFZiel, FO_READWRITE+FO_SHARED)) # 0 .and. FSEEK (nH, 0, FS_SET) # -1
* ID3V2 wird geschrieben
if (nNr:=FWrite(nH ,cT )) # 0 ; bV2:=.t.; endif
* ID3V1 erst prüfen ob schon vorhanden
if (FSEEK (nH, -1, FS_END) # -1)
FRead(nH, @cBuffer, 1)
if substr(cBuffer,1,1) = chr(255) // FF wenn vorhanden
FSEEK (nH, -128, FS_END)
endif
if (nNr:=FWrite(nH ,V1 )) # 0 ; bV1:=.t.; endif
endif
Fclose(nH)
if ! bV2 ; StopBox("ID3V2 konnte nicht geschrieben werden !", cFZiel); endif
if ! bV1 ; StopBox("ID3V1 konnte nicht geschrieben werden !", cFZiel); endif
else; StopBOX("Die Datei ["+cFZiel+"] wurde nicht aktualisiert !;;Win-Fehlernummer: "+TTOC(FError() ),"ID3PUT()"); nWrite:=0
endif
endif
return (nWrite)
-
- 1000 working lines a day
- Beiträge: 525
- Registriert: Mi, 01. Feb 2006 16:22
- Wohnort: 06618 Naumburg
Byte & Bit
irgendwie hängst es an der Umwandlung von Bytes in Bits.
Ich kann mir zwar die Bytes anzeigen lassen - ich bräuchte aber die Bits.
Das mit den ID-Tags ist zwar hilfreich, trifft aber glaube ich nicht ganz den Kern der Sache.
Ich bräuchte einfach die ersten 32 Bit des Headers der Datei. Was ich bisher gefunden habe geht das nur mit C oder VB
Ich kann mir zwar die Bytes anzeigen lassen - ich bräuchte aber die Bits.
Das mit den ID-Tags ist zwar hilfreich, trifft aber glaube ich nicht ganz den Kern der Sache.
Ich bräuchte einfach die ersten 32 Bit des Headers der Datei. Was ich bisher gefunden habe geht das nur mit C oder VB
- Martin Altmann
- Foren-Administrator
- Beiträge: 16586
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Byte & Bit
Hallo Peter,
Viele Grüße,
Martin
soweit ich weiß, kann man mit den Array-Operatoren bitweise auslesen. Es sollte also so gehen:peternmb hat geschrieben:Ich bräuchte einfach die ersten 32 Bit des Headers der Datei. Was ich bisher gefunden habe geht das nur mit C oder VB
Code: Alles auswählen
inhalt[1] // entspricht dem 1. Bit
inhalt[2] // entspricht dem 2. Bit
...
inhalt[32] // entspricht dem 32. Bit
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Martin Altmann
- Foren-Administrator
- Beiträge: 16586
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Ach Mensch - Du wolltest ja 32 Byte bitweise ausgelesen haben, sorry!! Ich war davon ausgegangen, dass in der Vairablen inhalt genau ein Byte steht!
Dann probiere es mal mit dem Konstrukt:
Klappt das denn dann wenigstens??
Viele Grüße,
Martin
Dann probiere es mal mit dem Konstrukt:
Code: Alles auswählen
inhalt[1][1] // entspricht dem 1. Bit des 1. Bytes
inhalt[1][2] // entspricht dem 2. Bit des 1. Bytes
...
inhalt[32][8] // entspricht dem 8. Bit des 32. Bytes
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Martin Altmann
- Foren-Administrator
- Beiträge: 16586
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Hallo Peter,
Komisch - in der Alaska-Newsgroups gibt es mehrere Postings zu dem Thema. Und da wurde gesagt, dass ab Xbase++ Version 1.7 das bitweise aulsesen einer Variablen über die Array-Operanden funktioneren soll.
Ich selber habe das noch nie gemacht - darum hatte ich auch geschrieben:
Du könntest höchstens noch mal den umständlichen Weg probieren - nur um sicher zu gehen:
Viele Grüße,
Martin
ja - das ist schon klar. Sonst wäre der Index ja auch [ 1, 2 ] gewesen.peternmb hat geschrieben:So wie es aussieht ist die Variable inhalt nur ein 1-dimensionales Array
Komisch - in der Alaska-Newsgroups gibt es mehrere Postings zu dem Thema. Und da wurde gesagt, dass ab Xbase++ Version 1.7 das bitweise aulsesen einer Variablen über die Array-Operanden funktioneren soll.
Ich selber habe das noch nie gemacht - darum hatte ich auch geschrieben:
Tut mir wirklich leid, dass ich Dir scheinbar nicht helfen kann!Martin Altmann hat geschrieben:soweit ich weiß, kann man mit den Array-Operatoren bitweise auslesen. Es sollte also so gehen:
Du könntest höchstens noch mal den umständlichen Weg probieren - nur um sicher zu gehen:
Code: Alles auswählen
FOR i := 1 to 32
byte := inhalt[ i ]
FOR j := 1 to 8
bit := byte[ j ]
...
NEXT
NEXT
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
-
- Rekursionen-Architekt
- Beiträge: 116
- Registriert: Fr, 23. Sep 2005 16:07
- Wohnort: Bad Oldesloe
- Kontaktdaten:
Hallo Peter,
habe mal vor langer Zeit mit Bits setzen und abfragen eine Programm geschrieben.
Schau die doch mal diese Programmzeilen genauer an, ich denke es könnte helfen.
Gruß
Thomas
habe mal vor langer Zeit mit Bits setzen und abfragen eine Programm geschrieben.
Schau die doch mal diese Programmzeilen genauer an, ich denke es könnte helfen.
Gruß
Thomas
Code: Alles auswählen
#include "fileio.ch"
proc say_header(cDatei)
LOCAL nHandle := 0, inhalt:=space(4)
nHandle := FOPEN(cDatei, FO_READ + FO_SHARED)
IF nHandle > 0
FREAD(nHandle, @inhalt,4) // 4 byte a 8Bit = 32 Bit auslesen
ENDIF
//
FCLOSE(nHandle)
// Test die ersten 8 Bits
cByte := SUBSTR(inhalt,1,1)
IF 2 $ VAL(cByte)
// Bit 1 ist gesetzt
ELSE
// Bit ist nicht gesetzt
ENDIF
IF 4 $ VAL(cByte)
// Bit 2 ist gesetzt
ENDIF
IF 2+8+32 $ VAL(cByte)
// Bit 1 und 3 und 5 sind gesetzt
ENDIF
cBitString := s_bit(VAL(cByte))
MsgBox(cBitString)
return
FUNCTION s_bit( nZahl )
LOCAL cStrg :=""
LOCAL nIx
FOR nIx = 7 TO 0 STEP -1
IF nZahl >= 2 ** nIx
nZahl := nZahl - 2 ** nIx
cStrg += "1"
ELSE
cStrg += "0"
ENDIF
NEXT nIx
RETURN( cStrg )
- Wolfgang Ciriack
- Der Entwickler von "Deep Thought"
- Beiträge: 2950
- Registriert: Sa, 24. Sep 2005 9:37
- Wohnort: Berlin
- Hat sich bedankt: 14 Mal
- Danksagung erhalten: 34 Mal
- Kontaktdaten:
- Martin Altmann
- Foren-Administrator
- Beiträge: 16586
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Hallo Peter,
ich kann es nicht lassen
Ich habe mal gerade in der Doku von Xbase++ gestöbert. Der folgende Abschnitt ist interessant - die fett-Formatierung dient dem Hervorheben der wichtigen Dinge:
Viele Grüße,
Martin
ich kann es nicht lassen
Ich habe mal gerade in der Doku von Xbase++ gestöbert. Der folgende Abschnitt ist interessant - die fett-Formatierung dient dem Hervorheben der wichtigen Dinge:
Und hier mal das entsprechende Beispiel aus der Doku:[] Operator hat geschrieben:Der Array-Operator ist nicht auf Werte vom Datentyp "Array" beschränkt, sondern kann auch auf Zeichenketten und numerische Werte angewandt werden. Hinweis: In der aktuellen Xbase++ Version ist der Operator bei Zuweisungen nur bei LOCAL oder STATIC Variablen, denen die Zeichenkette bzw. der numerischen Wert zugewiesen ist, anwendbar.
Zeichen Bei Zeichenketten gibt der Operator das Zeichen an der Position <nElement> aus der Zeichenkette zurück (siehe Beispiel unten). Das Ermitteln einzelner Zeichen aus einer Zeichenkette läuft mit dem Array-Operator sehr viel schneller ab als mit der Funktion SubStr().
Numerisch Wenn der Operand einen numerischen Wert hat, prüft der Operator, ob das Bit an der Position <nElement> gesetzt ist. Das Ergebnis der Operation ist .T. (wahr), falls das Bit gesetzt ist, andernfalls ist es .F. (falsch). Der Wert des Operanden kann auf Bit-Ebene verändert werden, indem der Wert .T. oder .F. für das Bit an der Position <nElement> zugewiesen wird. Der Wertebereich für <nElement> erstreckt sich bei numerischen Operanden von 1 bis 32.
Code: Alles auswählen
// Array-Operator und numerische Werte
// Das Beispiel zeigt wie der Array-Operator mit
// Werten vom Datentyp Numerisch verwendet werden kann.
PROCEDURE Main
LOCAL n
? n := 6 // Ergebnis: 6
? n[1] // Ergebnis: .F. (Bit für 2^0 ist nicht gesetzt)
? n[2] // Ergebnis: .T. (Bit für 2^1 ist gesetzt)
? n[3] // Ergebnis: .T. (Bit für 2^2 ist gesetzt)
n[1] := .T. // Bit für 2^0 setzen
? n // Ergebnis: 7
RETURN
Martin
Zuletzt geändert von Martin Altmann am Do, 16. Mär 2006 8:18, insgesamt 2-mal geändert.
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
-
- 1000 working lines a day
- Beiträge: 525
- Registriert: Mi, 01. Feb 2006 16:22
- Wohnort: 06618 Naumburg
muss ich mir nochmal in Ruhe ansehen, ich verstehe das bisher noch nicht so richtig
Ich bräuchte einfach die ersten 32 Bit des Dateiheaders als Zeichenkette.
Die 32 Zeichen würden dann, wenn ich alles halbwegs verstanden habe nur aus 32x 0 oder 1 bestehen.
Aber ich glaube, mit den bisherigen Infos ist es zu schaffen
Ich bräuchte einfach die ersten 32 Bit des Dateiheaders als Zeichenkette.
Die 32 Zeichen würden dann, wenn ich alles halbwegs verstanden habe nur aus 32x 0 oder 1 bestehen.
Aber ich glaube, mit den bisherigen Infos ist es zu schaffen
- andreas
- Der Entwickler von "Deep Thought"
- Beiträge: 1902
- Registriert: Mi, 28. Sep 2005 10:53
- Wohnort: Osnabrück
- Hat sich bedankt: 4 Mal
- Kontaktdaten:
Hallo Martin,
ich habe schon lange die Abfrage bzw. Setzen einzelner Bits gesucht.
Jetzt habe ich das aus deinem letzten Posting ausprobiert und in eine vorhandene Anwendung eingebaut.
Komischerweise kann ich die Bits abfragen aber nicht setzen.
Wenn ich aber den Code aus der Hilfe (auch in deimen Posting) als eigene Anwendung kompiliere, funktioniert es.
Was kann das sein?
ich habe schon lange die Abfrage bzw. Setzen einzelner Bits gesucht.
Jetzt habe ich das aus deinem letzten Posting ausprobiert und in eine vorhandene Anwendung eingebaut.
Komischerweise kann ich die Bits abfragen aber nicht setzen.
Wenn ich aber den Code aus der Hilfe (auch in deimen Posting) als eigene Anwendung kompiliere, funktioniert es.
Was kann das sein?
-
- 1000 working lines a day
- Beiträge: 525
- Registriert: Mi, 01. Feb 2006 16:22
- Wohnort: 06618 Naumburg
Beispielcode von Thomas
Hallo, ich habe den Beispielcode von Thomas mal so erweitert, dass die ersten 4 Byte à 8 Bit angezeigt werden, aber das Ergebniss verblüfft mich etwas. Es werden beim Einlesen von einer MP3-Datei nur die Bits 23 und 24 als gesetzt gezeigt. Der Rest sind alles Nullen. Das kann lt. der Header-Beschreibung aber nicht hinkommen. Ich glaube ich geb`s auf - ich kann mittlerweile keine Bits und Bytes mehr sehen
- Martin Altmann
- Foren-Administrator
- Beiträge: 16586
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Hallo Andreas,
Viele Grüße,
Martin
keine Ahnung - außer dass Deine Variable vielleicht weder vom Typ local noch vom Typ static ist?andreas hat geschrieben:Wenn ich aber den Code aus der Hilfe (auch in deimen Posting) als eigene Anwendung kompiliere, funktioniert es.
Was kann das sein?
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
re: MP3 TAG
moin,
da ich mich auch gerade mit den MP3 ID TAG beschäftige habe,
ein paar Anmerkungen :
a.) es gibt MP3 ID TAG v1.0 & v1.1 welche beide am ENDE der
Datei die letzten 128 Byte füllen.
{ID3-TAGv1 sind die letzten 128 Bytes
der Datei und sind so aufgeteilt:
Byte 1-3 = Kennung 'TAG' 3
Byte 4-33 = Titel 30
Byte 34-63 = Artist 30
Byte 64-93 = Album 30
Byte 94-97 = Jahr 4
Byte 98-127 = Kommentar 30 (28 Kommentar + 2 TrackNo.)
Byte 128 = Genre} 1 (0-79)
b.) die v2.0x MP3 ID TAG Version von der ihr hier sprecht ist "ein wenig"
komplizierter aufgebaut. siehe link
http://www.id3.org/develop.html
beim letzten war ich dran, bis ich feststellte das ich anders rankomme
da ich Xbase++ RC2 mit WMP.OCX benutze. Also kann ich aus der
WMP Playliste mit Hilfe des WMP Event "CurrentItemChange" von
jedem Item die "Property" auslesen und hab dann alle Informationen
die ich benötige.
gruss by OHR
Jimmy
da ich mich auch gerade mit den MP3 ID TAG beschäftige habe,
ein paar Anmerkungen :
a.) es gibt MP3 ID TAG v1.0 & v1.1 welche beide am ENDE der
Datei die letzten 128 Byte füllen.
{ID3-TAGv1 sind die letzten 128 Bytes
der Datei und sind so aufgeteilt:
Byte 1-3 = Kennung 'TAG' 3
Byte 4-33 = Titel 30
Byte 34-63 = Artist 30
Byte 64-93 = Album 30
Byte 94-97 = Jahr 4
Byte 98-127 = Kommentar 30 (28 Kommentar + 2 TrackNo.)
Byte 128 = Genre} 1 (0-79)
b.) die v2.0x MP3 ID TAG Version von der ihr hier sprecht ist "ein wenig"
komplizierter aufgebaut. siehe link
http://www.id3.org/develop.html
beim letzten war ich dran, bis ich feststellte das ich anders rankomme
da ich Xbase++ RC2 mit WMP.OCX benutze. Also kann ich aus der
WMP Playliste mit Hilfe des WMP Event "CurrentItemChange" von
jedem Item die "Property" auslesen und hab dann alle Informationen
die ich benötige.
gruss by OHR
Jimmy
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
@petermb
> Ich bräuchte einfach die ersten 32 Bit des Dateiheaders
> als Zeichenkette.
> Die 32 Zeichen würden dann, wenn ich alles halbwegs verstanden
> habe nur aus 32x 0 oder 1 bestehen.
NEIN, so funktioniert das nicht.
'0101' sind keine 4 Bit, sondern 4 Byte und der WERT der Variable intern ist nicht 0 oder 1 sondern '0' = ASC('0') = 48 und '1' = ASC('1') = 49
Wenn du eine String-Variable mit einem Byte hast, dann kann man leicht die Bits zuordnen:
00000000 -> chr(0)
00000001 -> chr(1) oder neuerdings bei numerisch nVal[1] := 1
00000010 -> chr(2) oder neuerdings bei numerisch nVal[2] := 1
00000011 -> chr(3) oder neuerdings bei numerisch nVal[2] := 1 und nVal[1] := 1
bei den neuen nVal[] Funktionen bin ich mir jetzt nicht sicher, da ich diese so nie brauche.
Ein 32 Bit Wert mit 1 sieht also intern so aus:
00000000 00000000 00000000 00000001 aber die Reihenfolge der Speicherung muß nicht unserer Lesart entsprechen.
In deinem Beispiel ganz am Anfang ließt du 32 BYTE ein, denn jeder Befehl in Xbase++, welcher auf Festplatten, Strings etc. zugreift arbeitet immer BYTE-weise !
Um 32 Bit zu bekommen mußt du 4 Byte einlesen (da 4 Byte * 8 Bit = 32 Bit). Wenn du dies aber in eine Stringvariable einliest, kannst du mit dem Arrayoperator nur auf einzelne BYTE (Zeichen, String = array of Byte in C ) zugreifen. Um mit dem Arrayoperator auf BIT Zugreifen zu können müßtest du die 4 Byte in eine Zahl verwandeln (VAL hilft hier nicht !), welche genaue Reihenfolge weiß ich im Moment auch nicht, aber im Prinzip so
asc(cString[1])+ asc(cString[2])*256 + asc(cString[3])*256*256 + asc(cString[4])*256*256*256
Das Problem ist, zu erkennen, welche der einzelnen Zeichen jetzt welchen Multiplikator braucht. Vor Jahren habe ich mit PowerBasic den Dateiheader von DBF Dateien zerlegt, da war zuerst das niederwertige Byte gespeichert dann das höherwertige - bei 16 Bit Werten.
Dummerweise gibt es in Xbase++ keine 32 Bit - INTEGER / DWORD Variablen. Hast du die Tools ? Dort gibt es Funktionen zu BIT Operationen, wie gut die sind weiß ich aber nicht. Mit den nVal[] Operatoren sollte es aber auch gehen.
Wichtig, man kann zwar aus einer 4 Byte Variablen (Stringlänge 4 oder Integer) einen 32 Byte langen String mit 0 und 1 machen, dieser hat aber keine 32 Bit sondern 32 BYTE, auch wenn er eventuell für dich nützlich wäre.
Solltest du dies bereits gewußt haben, sorry, aber ich habe den Eindruck, dass du bei Bit und Byte etwas durcheinander gebracht hattest.
Forsche nun nochmals die Beispiele weiter oben durch, eventuell paßt es dann ja.
> Ich bräuchte einfach die ersten 32 Bit des Dateiheaders
> als Zeichenkette.
> Die 32 Zeichen würden dann, wenn ich alles halbwegs verstanden
> habe nur aus 32x 0 oder 1 bestehen.
NEIN, so funktioniert das nicht.
'0101' sind keine 4 Bit, sondern 4 Byte und der WERT der Variable intern ist nicht 0 oder 1 sondern '0' = ASC('0') = 48 und '1' = ASC('1') = 49
Wenn du eine String-Variable mit einem Byte hast, dann kann man leicht die Bits zuordnen:
00000000 -> chr(0)
00000001 -> chr(1) oder neuerdings bei numerisch nVal[1] := 1
00000010 -> chr(2) oder neuerdings bei numerisch nVal[2] := 1
00000011 -> chr(3) oder neuerdings bei numerisch nVal[2] := 1 und nVal[1] := 1
bei den neuen nVal[] Funktionen bin ich mir jetzt nicht sicher, da ich diese so nie brauche.
Ein 32 Bit Wert mit 1 sieht also intern so aus:
00000000 00000000 00000000 00000001 aber die Reihenfolge der Speicherung muß nicht unserer Lesart entsprechen.
In deinem Beispiel ganz am Anfang ließt du 32 BYTE ein, denn jeder Befehl in Xbase++, welcher auf Festplatten, Strings etc. zugreift arbeitet immer BYTE-weise !
Um 32 Bit zu bekommen mußt du 4 Byte einlesen (da 4 Byte * 8 Bit = 32 Bit). Wenn du dies aber in eine Stringvariable einliest, kannst du mit dem Arrayoperator nur auf einzelne BYTE (Zeichen, String = array of Byte in C ) zugreifen. Um mit dem Arrayoperator auf BIT Zugreifen zu können müßtest du die 4 Byte in eine Zahl verwandeln (VAL hilft hier nicht !), welche genaue Reihenfolge weiß ich im Moment auch nicht, aber im Prinzip so
asc(cString[1])+ asc(cString[2])*256 + asc(cString[3])*256*256 + asc(cString[4])*256*256*256
Das Problem ist, zu erkennen, welche der einzelnen Zeichen jetzt welchen Multiplikator braucht. Vor Jahren habe ich mit PowerBasic den Dateiheader von DBF Dateien zerlegt, da war zuerst das niederwertige Byte gespeichert dann das höherwertige - bei 16 Bit Werten.
Dummerweise gibt es in Xbase++ keine 32 Bit - INTEGER / DWORD Variablen. Hast du die Tools ? Dort gibt es Funktionen zu BIT Operationen, wie gut die sind weiß ich aber nicht. Mit den nVal[] Operatoren sollte es aber auch gehen.
Wichtig, man kann zwar aus einer 4 Byte Variablen (Stringlänge 4 oder Integer) einen 32 Byte langen String mit 0 und 1 machen, dieser hat aber keine 32 Bit sondern 32 BYTE, auch wenn er eventuell für dich nützlich wäre.
Solltest du dies bereits gewußt haben, sorry, aber ich habe den Eindruck, dass du bei Bit und Byte etwas durcheinander gebracht hattest.
Forsche nun nochmals die Beispiele weiter oben durch, eventuell paßt es dann ja.
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Hi,
ich habe hier mal ein kleines Programm erstellt, welches die Bit und Byte einer 32 Bitzahl ausleuchtet:
und nun noch das Ergebnis:
Im Speicher ist es also einfacher als ich dachte und laut Beschreibung des ID-Tag sollte es auch dort einfach abgelegt sein. Meine Erinnerung bezog sich auf gepackte Datumsfelder.
ich habe hier mal ein kleines Programm erstellt, welches die Bit und Byte einer 32 Bitzahl ausleuchtet:
Code: Alles auswählen
procedure main
local cTxt, nWert, nSollWert
set alternate to test.txt
set alternate on
cls
? "Start"
for x := 1 to 32
cTxt := replicate("0",32) // immer löschen
cTxt[33-x] := "1" // wir lesen 1. Bit von rechts
nWert := 0 // immer löschen
nWert[x] := .t. // .t. = 1
nSollWert := int(2^(x-1))
? x,cTxt,nWert,nSollWert
next
? "Ende"
set alternate to
return
Code: Alles auswählen
Start
1 00000000000000000000000000000001 1 1
2 00000000000000000000000000000010 2 2
3 00000000000000000000000000000100 4 4
4 00000000000000000000000000001000 8 8
5 00000000000000000000000000010000 16 16
6 00000000000000000000000000100000 32 32
7 00000000000000000000000001000000 64 64
8 00000000000000000000000010000000 128 128
9 00000000000000000000000100000000 256 256
10 00000000000000000000001000000000 512 512
11 00000000000000000000010000000000 1024 1024
12 00000000000000000000100000000000 2048 2048
13 00000000000000000001000000000000 4096 4096
14 00000000000000000010000000000000 8192 8192
15 00000000000000000100000000000000 16384 16384
16 00000000000000001000000000000000 32768 32768
17 00000000000000010000000000000000 65536 65536
18 00000000000000100000000000000000 131072 131072
19 00000000000001000000000000000000 262144 262144
20 00000000000010000000000000000000 524288 524288
21 00000000000100000000000000000000 1048576 1048576
22 00000000001000000000000000000000 2097152 2097152
23 00000000010000000000000000000000 4194304 4194304
24 00000000100000000000000000000000 8388608 8388608
25 00000001000000000000000000000000 16777216 16777216
26 00000010000000000000000000000000 33554432 33554432
27 00000100000000000000000000000000 67108864 67108864
28 00001000000000000000000000000000 134217728 134217728
29 00010000000000000000000000000000 268435456 268435456
30 00100000000000000000000000000000 536870912 536870912
31 01000000000000000000000000000000 1073741824 1073741824
32 10000000000000000000000000000000 2147483648 2147483648
Ende
Gruß
Hubert
Hubert
-
- 1000 working lines a day
- Beiträge: 525
- Registriert: Mi, 01. Feb 2006 16:22
- Wohnort: 06618 Naumburg
Na, da werde ich mich doch nochmal mit den Bits & Byten befassen Ich glaube das Posting von Hubert bringt mich da jetzt eine Schritt weiter. Vielen Dank.
Das mit den ID3-Tags (wie weiter oben angesprochen) ist zwar auch interessant, liefert mir aber nicht die Informationen die ich eigentlich haben möchte (z.B. Samplingrate).
Das mit den ID3-Tags (wie weiter oben angesprochen) ist zwar auch interessant, liefert mir aber nicht die Informationen die ich eigentlich haben möchte (z.B. Samplingrate).