Autor |
Beitrag |
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mo 04.07.11 17:14
Das auslesen geht ja nur das zurückschreiben ins Array?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
|
zhler:= 0; a[0]:= $87; a[1]:= $40; a[2]:= 0; DezimalValue:= 0; repeat ByteValue:= a[zhler]; Inc(zhler); DezimalValue:= ((DezimalValue shl 7) + (ByteValue and $7f)); until (ByteValue and $80 = 0); |
und nun zurück ins Array ?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
|
a[0]:= 0;a[1]:= 0;a[2]:= 0;
zhler:= 0;
r:= DezimalValue; repeat b:= (r shr 7) + (r and $7f); a[zhler]:= (b); inc(zhler); r:= (r shr 7);
until b = 0; |
Egal wie ich es ansetzte,
Ich bekomme die bytes nicht in der Reihenfolge ins array. Die Anzahl der Bytes kann variieren!
Vielleicht könnt ihr da helfen?
Gruss Alf
Moderiert von Narses: Titel erweitert.
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.07.11 17:56
Moin!
ALF hat folgendes geschrieben : | Vielleicht könnt ihr da helfen? |
Also, wenn ich ehrlich bin: ich verstehe noch gar nicht, was du eigentlich machen willst...
ALF hat folgendes geschrieben : | Die Anzahl der Bytes kann variieren! |
Was genau soll das heißen? Du hast ja nativ nicht beliebig große Integer in Delphi...  Irgendein Maximum muss es ja geben, 32bit oder 64?
Willst du sowas machen? Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var x: Cardinal; a: array[0..3] of Byte;
x := $12345678; a[0] = $78; a[1] = $56; a[2] = $34; a[3] = $12; | Oder sollen die höherwertigen Bits zuerst im Array landen?
Sowas hast du schonmal gesehen?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| type TIntAsByte = record case boolean of FALSE: (asByte: array[0..3] of Byte); TRUE: (asInt: Integer); end; var x: TIntAsByte; begin x.asInt := $12345678; ShowMessage(IntToHex(x.asByte[0],2)); ShowMessage(IntToHex(x.asByte[1],2)); ShowMessage(IntToHex(x.asByte[2],2)); ShowMessage(IntToHex(x.asByte[3],2)); | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mo 04.07.11 18:48
Klar, wie immer doof Formuliert
Das ganze kommt aus den MIDIFile bereich. Das auslesen, dabei ist das MSB zu beachten funct ja auch.
Nun will ich die Dezimalzahl wieder zurückschreiben, dabei ist das MSB auch wieder zu beachten.
Zitat: | Oder sollen die höherwertigen Bits zuerst im Array landen?
|
jo so ist es.
Da beim auslesen des Arrays es ja relativ einfach geht, müsste es doch umgekehrt in etwa genau so ablaufen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| b:= (r shr 7) + (r and $80); a[zhler]:= b; inc(zhler); .... b := (r and $7f);.... |
Es geht also darum, alles in richtiger Reienfolge in der Schleife zu bringen.
Sowas ist für mich ein graus
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.07.11 19:22
Moin!
OK, endianess ist geklärt: MSB (=Motorola, Netzwerk). Aber das sieht mir so nach 7-bit aus (ich erinnere mich nur noch sehr düster an die MIDI-Spec). Kannst du da mal eben die Spec zitieren, wie das Protokoll genau aussieht? War da nicht was mit max. 16bit im MIDI-Format?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
Zuletzt bearbeitet von Narses am Mo 04.07.11 20:24, insgesamt 1-mal bearbeitet
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mo 04.07.11 20:01
MSB = MostSignifikantBit $80
Genauer geht es um den DeltaTimeWert. Dieser Wert ist in der Anzahl an Byte variable.
Wenn Dezimalwert > 127($7f) 7Bits, wird das MSB gesetzt und ein weiteres Byte zum ablegen angefordert.
dann Dezimalwert mit shr7(7bits) schieben usw bis Dezimalwert 0.
Im MIDI ist fast alles nur auf 7bits oder 4bits ausgelegt
Wurde aber auch hier im Forum schon beschrieben. Nur wie man den Deltatimewert zurück schreibt hab ich nix gefunden noch nichtmal google.
Wie es also funcen muss weiss ich, aber an der Umsetztung scheitert es, wo was an welcher Stelle stehen muss um dieses Array wieder zu füllen.
Natürlich kann ich es mit if machen, es müsste doch aber, wie beim auslesen, auch so zurückgehen!?
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.07.11 20:29
Moin!
Meinst du sowas in der Art?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var Value: Integer; b: Byte; begin Value := $12345678; repeat b := Value and $7f; Value := Value shr 7; if (Value > 0) then b := b or $80; Memo1.Lines.Add(IntToHex(b,2)); until b = 0; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mo 04.07.11 20:56
So ähnlich hab ich es schon durch. Nur das Ergebnis stimmt nicht.
Ausgehend vom Eingangspost {------auslesen des Arrays und umwandel in Dezimalzahl---}
Ergebnis ist dezimal 960
So kommt beim zurückschreiben $C0 und $07 raus, müsste aber $87 und $40 stehen.
Ist also aucgh nicht die Lösung, weil irgendwo noch was fehlt.
Einzeln gesetzt erhalte ich ja das richtige
b:= (r shr 7) + (r and $80);//<--- b = $87
b := (r and $7f);//<--- b = $40
aber so funct es ja nicht in einer schleife
Oder besser, bin zu blöd dafür.
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.07.11 22:45
Moin!
Hm, doch nicht so trivial, wie´s auf den ersten Blick ausgesehen hat...
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:
| type TForm1 = class(TForm) meLog: TMemo; edValue: TEdit; btnStart: TButton;
procedure TForm1.btnStartClick(Sender: TObject); var Value: Cardinal; Size, i: Integer; bytes: array[0..3] of Byte; begin meLog.Clear; Value := StrToIntDef(edValue.Text,0); if (Value = 0) then begin meLog.Lines.Add('$00'); Exit; end; if (Value > $FFFFFFF) then raise Exception.Create('Value exceeds MIDI constraints!'); i := Value; Size := 0; while (i > 0) do begin i := i shr 7; Inc(Size); end; for i := Size-1 downto 0 do begin bytes[i] := Value and $7f; Value := Value shr 7; if (i <> Size-1) then bytes[i] := bytes[i] or $80; end; for i := 0 to Size-1 do meLog.Lines.Add('$'+IntToHex(bytes[i],2)); | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
Für diesen Beitrag haben gedankt: ALF
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mo 04.07.11 23:22
Nice
Wenn Du schon sagst:
Narses hat folgendes geschrieben : | Hm, doch nicht so trivial, wie´s auf den ersten Blick ausgesehen hat...  |
wie soll ich depp auf so was kommen
Sämtlich Literatur durchgelesen auch diese Seite. Überall steht da wie man das ganze ausliest und wie sie im Hexiditor stehen.
Nur ganz wenige MIDIwriter.pas gefunden. Wie man aber den DeltaTimeWert schreibt, hab ich dort nicht gefunden.
Und ich häng schon 3 Tage dran + Suche
Na dan Danke ich für diese suuuper Hilfe
EDIT: Auch noch was gefunden. community.freepascal...0&forum_id=24111 Und gleich mal umgesetzt ist ne Optimierung.
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:
| var MyArray: Array [0..4] of Byte; ArrayPos: integer; DezDeltaTime: integer; HexMask: DWord; zhler: integer; begin
DezDeltaTime:= 380160; ArrayPos:= 0; zhler:= 0; HexMask:= ((DezDeltaTime and $7F); While DezDeltaTime > 0 do begin DezDeltaTime:= (DezDeltaTime shr 7); if DezDeltaTime <> 0 then HexMask:= (HexMask shl 8); HexMask:= HexMask or ((DezDeltaTime and $7F) or $80); inc(zhler); end;
While zhler > 0 do begin MyArray[ArrayPos]:= LoWord(LoByte(HexMask)); HexMask:= (HexMask shr 8); inc(ArrayPos); dec(zhler); end; end; |
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|