Autor Beitrag
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Mo 04.07.11 17:14 
Das auslesen geht ja nur das zurückschreiben ins Array?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
{------auslesen des Arrays und umwandel in Dezimalzahl---}

 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 ?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
{-----DezimalZahl zurück ins Array-------}

a[0]:= 0;//<--$87
a[1]:= 0;//<--$40
a[2]:= 0;

zhler:= 0;

r:= DezimalValue;
repeat
  b:= (r shr 7) + (r and $7f);//(r and $80)
  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 user profile iconNarses: Titel erweitert.

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 04.07.11 17:56 
Moin!

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
Vielleicht könnt ihr da helfen?
Also, wenn ich ehrlich bin: ich verstehe noch gar nicht, was du eigentlich machen willst... :gruebel:

user profile iconALF hat folgendes geschrieben Zum zitierten Posting springen:
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?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
  x: Cardinal;
  a: array[0..3of Byte;

x := $12345678;
// Dinge tun, so dass -->
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? ;)
ausblenden 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..3of 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
 b:= (r shr 7) + (r and $80);//<--- b = $87
 a[zhler]:= b;
 inc(zhler);
....  //<-- aber wie weiter???

//oder
b := (r and $7f);//<--- b = $40
....//<-- aber wie weiter ,(r := r shr 7) muss ja auch noch rein

Es geht also darum, alles in richtiger Reienfolge in der Schleife zu bringen.
Sowas ist für mich ein graus :cry:

Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: 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

_________________
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 04.07.11 20:29 
Moin!

Meinst du sowas in der Art? :gruebel:
ausblenden 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 > 0then
      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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 04.07.11 22:45 
Moin!

Hm, doch nicht so trivial, wie´s auf den ersten Blick ausgesehen hat... :?
ausblenden volle Höhe 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;

// http://cs.fit.edu/~ryan/cse4051/projects/midi/midi.html#vlq
procedure TForm1.btnStartClick(Sender: TObject);
  var
    Value: Cardinal;
    Size, i: Integer;
    bytes: array[0..3of Byte;
begin
  meLog.Clear;
  Value := StrToIntDef(edValue.Text,0); // Wert aus der GUI holen
  if (Value = 0then begin // Trivialfall 0 ausschließen
    meLog.Lines.Add('$00');
    Exit;
  end;
  if (Value > $FFFFFFFthen // Zu große Werte auch ausschließen
    raise Exception.Create('Value exceeds MIDI constraints!');
  // Bereich OK, nach MIDI-Spec umwandeln
  i := Value;
  Size := 0// rausfinden wieviele Bytes das gibt, weil wir rückwärts laufen müssen (MSB first!)
  while (i > 0do begin
    i := i shr 7;
    Inc(Size);
  end;
  for i := Size-1 downto 0 do begin // vom LSB zum MSB
    bytes[i] := Value and $7f// 7 Bit abspalten
    Value := Value shr 7;
    if (i <> Size-1then // bei allen ausser dem letzten Wert Bit 7 setzen -> VLQ-Protokoll
      bytes[i] := bytes[i] or $80;
  end;
  for i := 0 to Size-1 do // Werte vom MSB zum LSB ausgeben
    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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Mo 04.07.11 23:22 
Nice 8)
Wenn Du schon sagst:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
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. community.freepascal...0&forum_id=24111 Und gleich mal umgesetzt ist ne Optimierung.

ausblenden volle Höhe 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..4of Byte;//<--dient nur zur Demo
  ArrayPos: integer;           //<--dient nur zur Demo 
  DezDeltaTime: integer;       //<--dient nur zur Demo

  HexMask: DWord;
  zhler: integer;
begin
{-- DezDeltatime ist die Zeit vor einem Event --}
{-- ArrayPos währe die aktuelle Position im Array --}
  DezDeltaTime:= 380160;//960 ist der Zeitwert 1/4Note, 380160 ist ein vielfaches davon ;
  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 $7For $80);
     inc(zhler);
  end;

{-- und nun den Hexwert in richtiger Reihenfolge ablegen --} 
  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!