Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Array of Byte in dezimalzahl und zurück? (MIDI-VLQ)
ALF - Mo 04.07.11 17:14
Titel: Array of Byte in dezimalzahl und zurück? (MIDI-VLQ)
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.
Narses - 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... :gruebel:
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... :nixweiss: 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
ALF - Mo 04.07.11 18:48
Klar, wie immer doof Formuliert :cry:
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 :cry:
Gruss Alf
Narses - 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? :idea: :les: ;)
cu
Narses
ALF - 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 :wink:
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
Narses - Mo 04.07.11 20:29
Moin!
Meinst du sowas in der Art? :gruebel:
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
ALF - 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 :evil:
Oder besser, bin zu blöd dafür.
Gruss Alf
Narses - Mo 04.07.11 22:45
Moin!
Hm, doch nicht so trivial, wie´s auf den ersten Blick ausgesehen hat... :?
Delphi-Quelltext
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
ALF - Mo 04.07.11 23:22
Nice 8)
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 :shock:
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 :zustimm:
EDIT: Auch noch was gefunden.
http://community.freepascal.org:10000/bboards/message?message_id=274980&forum_id=24111 Und gleich mal umgesetzt ist ne Optimierung.
Delphi-Quelltext
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
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!