Seite 1 von 2

Auslesen einer binären Datei

Verfasst: 10.10.2025 12:39
von H.Brill
Hallo, ich habe etwas Probleme, eine binäre Datei mit einem XML-Vorspann (von einem elektr. Arkordeon) auszulesen. In dem XML-Vorspann steht dann bei
<SET size="26038" number="1400" offset="0">
die Größe der Registrierungen (26038 Bytes). Die .upa-Datei umfaßt genau 100 Bänke mit jeweils 14 Registrierungen (100 X 14 = 1400). Das sind also 1400 Registrierungen, an denen jeweils bei Offset $39B ein 20 Bytes langer 7Bit-Ascii - String steht, der den Titel beinhaltet. Zum Ende können diese
Titel auch leer sein, je nachdem wieviele halt gespeichert wurden. Aber zuerst will ich mal den Startoffset finden.
Es scheint so, als daß ich den richtigen Anfangs-Offset nicht genau bestimmen kann. Die Anzahl der XML-Einträge kann auch etwas variieren. Bei manchen Dateien fehlt dann die <UPLIST....>, so daß man vorher keinen fest definierten Startoffset festlegen kann.
Der relevante Teil sieht dann so aus :
a<?xml version="1.0" encoding="utf-8"?>
<Roland_Fr_UPA>
<SET size="26038" number="1400" offset="0">
<SC size="128" number="1" offset="0"/>
<O_R size="86" number="26" offset="128"/>
<OB_R size="66" number="7" offset="2364"/>
<OBC_R size="72" number="8" offset="2826"/>
<OFB_R size="72" number="8" offset="3402"/>
<TR size="304" number="16" offset="3978"/>
<BR size="84" number="16" offset="8842"/>
<BCR size="96" number="16" offset="10186"/>
<ORR size="64" number="26" offset="11722"/>
<OBR size="42" number="7" offset="13386"/>
<OBCR size="124" number="8" offset="13680"/>
<OFBR size="118" number="8" offset="14672"/>
<ORCH1 size="210" number="28" offset="15616"/>
<ORCH2 size="152" number="28" offset="21496"/>
<SC2 size="286" number="1" offset="25752"/>
</SET>
<UPLIST size="131072" number="1" offset="36453200"/>
</Roland_Fr_UPA>
�Ikxԛ�`�� �dT� @ ��P � @ ( s�
Im Original sind da vor den spitzen Klammern noch TABs drin, die die Forensoftware hier abgeschnitten hat.
hinter dem XML gibt es noch 7 Bytes (eine Art Magic-Header), den man überspringen muß.
Ich habe von einem Freund zwar ein Kommandozeilentool, möchte es aber auf Windows mit GUI (z.b. Listbox) portieren.
Das Tool gibt mir auch eine Textdatei mit den Titeln aus :
Hier mal die ersten 50 Titel :
upg_all 001 "UsrPrg DALE ON"
upg_all 002 "Classic 8"
upg_all 003 "ALPINE"
upg_all 004 "Mandolin"
upg_all 005 "TRUMPET"
upg_all 006 "CLARINET"
upg_all 007 "Low BRASS"
upg_all 008 "MASTER"
upg_all 009 "Sax Ensemble)Muss"
upg_all 010 "BASSoonSAX"
upg_all 011 "Musette16 (GTR)"
upg_all 012 "PIANO"
upg_all 013 "Twang GTR"
upg_all 014 "BRASS SYNTH"
upg_all 015 "Addams Family"
upg_all 016 "MISTY Jazz GTR"
upg_all 017 "HARRY POTTER"
upg_all 018 "GHOST RIDER"
upg_all 019 "BALL PARK ORGAN"
upg_all 020 "HarmoniCATS"
upg_all 021 "UNDER THE SEA"
upg_all 022 "STAR WARS"
upg_all 023 "NeverOnSunday"
upg_all 024 "GHOST RIDER"
upg_all 025 "Don't Worry"
upg_all 026 "SALOON BAND"
upg_all 027 "Star Trek"
upg_all 028 "BagPipe"
upg_all 029 "ART Van Damme"
upg_all 030 "GIRL FROM"
upg_all 031 "Accord_Organ"
upg_all 032 "Cordovox 8'"
upg_all 033 "CORDOVOX"
upg_all 034 "BIG BAND"
upg_all 035 "SwingOrgan"
upg_all 036 "MoscowNights"
upg_all 037 "ALPINE Master"
upg_all 038 "BesameMucho"
upg_all 039 "SingInTheRain"
upg_all 040 "PianoStringBallad"
upg_all 041 "PIANOmellow"
upg_all 042 "HAWAIIAN GTR"
upg_all 043 "THEATER1"
upg_all 044 "THEATER2"
upg_all 045 "THEATER3"
upg_all 046 "THEATER4"
upg_all 047 "SYNTH 5"
upg_all 048 "THEATER6"
upg_all 049 "HORN7"
upg_all 050 "SYNTH KLAR"
Das möchte ich dann mit PB gerne nachbauen. Wenn ich da den richtigen Startoffset hätte, wäre mir schon viel geholfen.
Wie kann man jetzt die genaue Stelle
�Ikxԛ�`�� �dT�
+ halt die 7 Bytes programmtechnisch genau ermitteln ?

Re: Auslesen einer binären Datei

Verfasst: 10.10.2025 15:33
von Axolotl
Hier mal zwei Konzepte (skins and bones) wie man vorgehen kann/könnte.... Vielleicht ist das ja eine Starthilfe

Um die jeweilige Stelle in der Datei/Speicher zu analysieren helfen a.m.S. auch eine der beiden folgenden Zeilen:

Code: Alles auswählen

ShowMemoryViewer(*Buffer, 100) 
Debug PeekS(*Buffer, 20, #PB_Ascii) 

Code: Alles auswählen

#FILE_READ = 1 

; First Trail 
;
Procedure AnalyzeFile(FileName$) 
  Protected text$, ffmt 

  If ReadFile(#FILE_READ, FileName$)
    ffmt = ReadStringFormat(#FILE_READ) 
;   If ffmt = #PB_Ascii Or ffmt = #PB_UTF8 Or ffmt = #PB_Unicode 
;   EndIf 
    text$ = ReadString(#FILE_READ, ffmt|#PB_File_IgnoreEOL) 
    CloseFile(#FILE_READ)
  EndIf

  p = FindString(text$, "�Ikxԛ�`�� �dT�") ; <= search for the magic string 
  If p 
    ; do the magic ..... 
  EndIf 
EndProcedure 

; Second Trail 
;
Procedure AnalyzeFile(FileName$) 
  Protected *Buffer, BufLength, *Signature, SigLength, ffmt 
  Protected *Cursor.ASCII  

  *Buffer = 0
  If ReadFile(#FILE_READ, FileName$)
    BufLength = Lof(#FILE_READ)
    *Buffer = AllocateMemory(BufLength + 10) ; avoid the 0 size-buffer problem (acc. to the PB source code) 
    If *Buffer 
      ffmt = ReadStringFormat(#FILE_READ)         ; now the pointer is behind the BOM (if any) 
      ReadData(#FILE_READ, *Buffer, BufLength) 
    EndIf
    CloseFile(#FILE_READ)
  EndIf

  ; search for the magic string ....  ?? ==> �Ikxԛ�`�� �dT� 
  SigLength = 14 
  *Signature AllocateMemory(SigLength + 1)        ; text size in bytes + null-cahr 
  PokeS(*Signature, "�Ikxԛ�`�� �dT�", -1, ffmt)   ; terminating null-char is written, compare without null-char  

  If *Buffer
    *Cursor = *Buffer 
    While *Cursor And *Cursor\a 
      If CompareMemoryString(*Cursor, *Signature, 0, SigLength, ffmt) = 0 
        ; do the magic ..... 

      EndIf
      *Cursor + 1   ; SizeOf(ASCII) 
    Wend
    FreeMemory(*Buffer)
    FreeMemory(*Signature) 
  EndIf
EndProcedure 

Re: Auslesen einer binären Datei

Verfasst: 10.10.2025 17:32
von H.Brill
Danke schon mal für den Code. Werde es mal morgen früh testen. Heute abend habe ich noch Ausgang.
Also, da muß ich wohl die ganze Datei zuerst in ein Memory lesen. Die hat 35.728 KB. Dachte, man könnte
es am Ende des XML irgendwie festmachen und dann häppchenweise (26038 bytes als Memorystück) weiter lesen.
Ist aber auch egal bei dem heutigen riesigen Speicher.

Re: Auslesen einer binären Datei

Verfasst: 10.10.2025 18:04
von Axolotl
Man kann auch blockweise einlesen, ist dann unter Umständen an den Bereichsgrenzen schwieriger..
Oder man nimmt

Code: Alles auswählen

ReadCharacter
ReadAsciiCharater
um die Zeichen einzeln einzulesen.

Man kann die Datei auch von hinten durchsuchen..

Code: Alles auswählen

length = Lof(0)                            ; get the length of opened file
; .....
*Cusor = *Buffer + length - sizeof(Charater)  ; last char/byte in file 

Re: Auslesen einer binären Datei

Verfasst: 10.10.2025 18:31
von HeX0R
Ich würde hier nicht mit Strings arbeiten, das bringt ja auch nichts, weil der binäre Teil dann eh abgeschnitten wäre.
Mein Vorschlag wäre, die ganze Datei in einen MemoryBuffer lesen.
Dann gehst Du das von vorne durch und nimmst CompareMemory(), um den Magic Header zu finden.
Du packst also den Magic Header in einen anderen MemoryBuffer und vergleichst dagegen immer (byteweise hochzählen).
Wenn Du ihn gefunden hast, kennst Du die Stelle und kannst alles davor mittels PeekS auslesen und das dahinter dann als Binärdaten verarbeiten.

Re: Auslesen einer binären Datei

Verfasst: 10.10.2025 18:40
von H.Brill
Ich habe da gerade noch was in einem Elektronik-Forum gefunden :
Die richtigen Angaben zu den Datenstrukturen holt man sich am besten
direkt aus den UPA Dateien.

Der Aufbau einer UPA Datei ist relativ einfach:

EF BB BF : Magic
4 Bytes : Länge des XML Header (Big-Endian)
XML Header : XML mit weiteren Angaben zu den Daten
die einzelnen Sets : Anzahl und Größe entsprechend dem XML Header
"UPLIST" : Bedeutung unklar, für die Sets wohl nicht relevant

Die einzelnen Sets fangen also ab Offset "7 + Länge des XML Header" an,
die Anzahl und Größe ergibt sich aus dem XML Header.

Zum XML Header, der ist eigentlich selbsterklärend, es wird der Aufbau
der Daten beschrieben, die relevanten Teile:

für den Fr: <SET size="26038" number="98" offset="0">
-> 98 Sets mit je 26038 Bytes
für den Fr-8x: <SET size="25752" number="1400" offset="0">
-> 1400 Sets mit je 25752 Bytes

Der Unterschied in der Setgröße zwischen Fr und Fr-8x ergibt sich aus
dem fehlenden "SC2" Eintrag beim Fr-8x.

Der Aufbau eines Sets wird ebenfalls im XML Header beschrieben, hier für
den Fr:

<SC size="128" number="1" offset="0"/>
<O_R size="86" number="26" offset="128"/>
<OB_R size="66" number="7" offset="2364"/>
<OBC_R size="72" number="8" offset="2826"/>
<OFB_R size="72" number="8" offset="3402"/>
<TR size="304" number="16" offset="3978"/>
<BR size="84" number="16" offset="8842"/>
<BCR size="96" number="16" offset="10186"/>
<ORR size="64" number="26" offset="11722"/>
<OBR size="42" number="7" offset="13386"/>
<OBCR size="124" number="8" offset="13680"/>
<OFBR size="118" number="8" offset="14672"/>
<ORCH1 size="210" number="28" offset="15616"/>
<ORCH2 size="152" number="28" offset="21496"/>
<SC2 size="286" number="1" offset="25752"/>

Der Offset ergibt sich aus der Länge der davor liegenden Daten, der
Aufbau des Sets ist aber wohl für das Zerlegen der UPA Dateien nicht
relevant.

Inwieweit der fehlende "SC2" Eintrag beim Fr-8x wichtig ist und
eventuell beim Zerlegen neu erzeugt werden muss ist unklar.

Und dann gibt es am Ende der UPA Dateien noch die "UPLIST", die steht
auch im XML Header, hier wieder für den Fr:

<UPLIST size="131072" number="1" offset="2551724"/>

Der Offset ergibt sich aus den davor liegenden Sets.

In der Beispiel Datei "UPG_ALL.UPA" steht dort nichts, in der Datei
"vom_8_UPG_ALL.UPA" für den Fr-8x steht dort etwas, die Bedeutung ist
unklar.
Vielleicht noch zur Verdeutlichung : das FR ist das kleinere Modell mit weniger Bänken und Registrierungen und das Frx8
ist das größere unt teuerere Modell, das mein Bekannter nutzt.

Also setzen sich da die besagten 7 Bytes aus
EF BB BF + 4 Bytes (Länge des XML-Headers) zusammen. Diese 4 Bytes (Big Endian) müßte man doch entschlüsseln können.
Vielleicht kann man damit etwas machen.
.

Re: Auslesen einer binären Datei

Verfasst: 10.10.2025 18:46
von HeX0R
Du solltest die Datei mal in einem Hex Editor anschauen, offensichtlich sind da ja nicht nur Tabs vor den spitzen Klammern.
Und EF BB BF is nichts als ein UTF-8 BOM

Re: Auslesen einer binären Datei

Verfasst: 11.10.2025 08:13
von H.Brill
Aha, das mit dem UTF8 war mir da gar nicht so bewußt. Da der BOM ja hinter dem XML steht, gilt das ja dann für die ganze nachfolgende Datei.
Ein UTF-8 BOM (Byte Order Mark) ist eine spezielle Bytefolge am Anfang einer UTF-8-Datei, die als Kennzeichnung für die Kodierung dient. Die Bytes sind $EF BB BF$. In UTF-8 ist es eigentlich nicht notwendig, da es keine Byte-Reihenfolge gibt, aber es kann Probleme verursachen, wenn Software es nicht richtig interpretiert, z. B. indem es als sichtbare Zeichen wie $$ angezeigt wird.
Das erfordert dann auch eine andere Herangehensweise, um die Musiktitel zu finden.

Re: Auslesen einer binären Datei

Verfasst: 11.10.2025 12:03
von Axolotl
H.Brill hat geschrieben: Gestern 08:13 .....
Das erfordert dann auch eine andere Herangehensweise, um die Musiktitel zu finden.
A.m.S. (eigentlich) nicht. Haste die o.g. Vorschläge mal ausprobiert?
Es klingt für mich aber alles machbar.
Da ich jedoch nicht genau weiß was das für Dateien sind und ich (deshalb) keinen Zugriff habe, kann ich (leider) nicht besser helfen.

Ansonsten bleibt dir ja noch das Consolen-Tool per RunProgram aufzurufen... (Als Plan D....)

Re: Auslesen einer binären Datei

Verfasst: 11.10.2025 12:45
von H.Brill
Hallo,
deine Codes hatte ich noch nicht ausprobiert, da Hexor meinte, nicht mit Strings zu hantieren.
Werde es aber dennoch nachholen.
Ich habe mal eine RolandFrxSettings.zip bei einem Filehoster hochgeladen, falls jemand interessiert ist.
Da ist das Konsolenprogramm, eine kleine Textdatei von mir, die die Aufrufparameter beschreibt und natürlich
so eine .upa Datei dabei. Das Konsolen-Tool kann auch so eine .upa Datei in 1400 Regristrierungsdateien zerstückeln.
Das wäre dann, wenn ich schon dabei bin, das nächste Ziel. Den Plan D hatte ich schon mal in XProfan gemacht und
läuft eigentlich. Mein Freund, der so ein Akkordeon (FRx8) hat, kann das zwar auch auf seinem Akkordeon machen,
bloß sei das eine richtige Fingerakrobatik. Deshalb wäre dem ein Windowsprogramm lieber, mit dem er dann später
seine Kompositionen (für Geburtstage u. s. Feste), die aus einzelnen Registrierungen besteht, zusammenstellen kann
und an das Instrument per USB schicken kann. Oder auch mit anderen Kollegen austauschen.
Hier der Link :

https://jottacloud.com/s/420c8f0f37862b ... 3bd1c4e848

Der Autor des Konsolenprogramms möchte sich nicht weiter damit beschäftigen. Somit kommt von ihm auch kein
Windowsprogramm. Auch eine .DLL macht er nicht. Da bräuchte man nicht nochmals das Rad neu erfinden.