Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Debugger Krise (https://www.delphipraxis.net/160366-debugger-krise.html)

EWeiss 9. Mai 2011 23:55

Debugger Krise
 
Delphi und meine wenigkeit mögen sich bald nicht mehr.

Wie aknn es sein das ein wert von 0 ausgegeben wird obwohl ersichtlich
dieser einen von 62 hat ?

Delphi-Quellcode:
      if FileInfo.MIDINotes[IntI, byte(FileInfo.MIDINotes[IntA])].NoteNo = 0 then
        Grid[IntI - 1, IntA] := -1;
IntI = 1 und IntA = 0
Result:= 60; // Richtig
IntI = 1 und IntA = 1
Result:= 0 ???

Man kann sehr deutlich sehen das hier der wert 62 steht.

Wichtig!
Auf das angehängte Bild schauen.

gruss

s.h.a.r.k 10. Mai 2011 00:40

AW: Debugger Krise
 
Ich kenne nur ein Phenomän, wenn Delphi die for-Schleife optimiert und der Debugger nicht darauf achtet. Wobei lediglich die Darstellung falsch ist, intern aber alles korrekt abläuft.

Sehe ich das schon richtig, dass die Zeile unter dem if ausgeführt wird, ob wohl 62 nicht gleich 0 ist?!

EWeiss 10. Mai 2011 00:45

AW: Debugger Krise
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1099886)
Ich kenne nur ein Phenomän, wenn Delphi die for-Schleife optimiert und der Debugger nicht darauf achtet. Wobei lediglich die Darstellung falsch ist, intern aber alles korrekt abläuft.

Sehe ich das schon richtig, dass die Zeile unter dem if ausgeführt wird, ob wohl 62 nicht gleich 0 ist?!

Das ist mein Problem!

Noch zwei pics da kann man sehen das beide IntI und IntA den wert 1 haben.
Wenn du oben dann vergleichst wirst du sehen das er trotzdem die Note löscht obwohl vorhanden.

Was soll ich denn jetzt machen.. grrrr
Optimierung habe ich ausgeschaltet alle DCU's glöscht und komplett neu Kompiliert.
Damit ich die Values verfolgen kann.

EDIT:
Hab es mal mit Packed Record versucht.. bringt auch nix.

Hier ist die Funktion vielleicht gibt es da ein problem denke aber nicht!
Delphi-Quellcode:
procedure TMidiTracker.ImpMidiFile(MidiFile: Widestring);
var
  FileInfo: TMIDIFileInfo;
  IntI: Integer;
  IntA: Integer;

begin
  if not ReadMIDIFile(MidiFile, FileInfo) then
  begin
    MessageBox(Self.Handle, 'Not a valid MIDI file.', 'Confirm', MB_OK);
    exit;
  end;

  for IntI := 1 to FileInfo.Tracks do
  begin
    for IntA := 0 to FileInfo.NoteCounter[IntI] -1 do
    begin
      if FileInfo.MIDINotes[IntI, byte(FileInfo.MIDINotes[IntA])].NoteNo = 0 then
        Grid[IntI - 1, IntA] := -1;

      if FileInfo.MIDINotes[IntI, (byte(FileInfo.MIDINotes[IntA]))].NoteNo > 0 then
      begin
        if FileInfo.MIDINotes[IntI, (byte(FileInfo.MIDINotes[IntA]))].Length = 12 then
          Grid[(IntI - 1), IntA] := (127 - FileInfo.MIDINotes[IntI, (byte(FileInfo.MIDINotes[IntA]))].NoteNo) + basenote;

        if FileInfo.MIDINotes[IntI, byte(FileInfo.MIDINotes[IntA])].Length > 12 then
          Grid[(IntI - 1), IntA] := 1000 + (127 - FileInfo.MIDINotes[IntI, (byte(FileInfo.MIDINotes[IntA]))].NoteNo + basenote);
      end;

      InstGrid[(IntI - 1), IntA] := FileInfo.MIDINotes[IntI, (byte(FileInfo.MIDINotes[IntA]))].Instrument;
    end;
  end;
  DrawGrid(self.Handle);

end;
gruss

EWeiss 10. Mai 2011 01:11

AW: Debugger Krise
 
Ist eh keiner Online...

also hier die records..
Wenn da nichts ist weiss ich auch nicht mehr.

Delphi-Quellcode:
type
  TMIDINote = record
    StartTime: DWORD;   // Start time of note in ticks
    Length: Word;       // Length of note in ticks (Length / Ticks : 1 => 1/4 note, 2 => 1/2 note...)
    NoteNo: byte;       // Note #
    Instrument: byte;
    Velocity: byte;
  end;

  TMIDIFileInfo = record
    FileSize: Int64;   { File size (bytes) }
    Format: Word;      {0: single-track, 1: multiple tracks, synchronous, 2: multiple tracks, asynchronous}
    Tracks: Word;
    TrackNames: array[1..MaxTracks] of AnsiString;
    TickUnit: Word;    {0: Ticks per quarter note, 1: Ticks per second}
    Ticks: Word;       {Ticks per quarter note or Ticks per second}
    Marker: AnsiString;
    Copyright: AnsiString;
    Channels: byte;
    PlayTime: single;
    NoteCounter: array[1..MaxChannels] of Word;    // The number of note per channel
    DrumChannel: array[1..MaxChannels] of Boolean; // True if it's a drum channel
    MIDINotes: array[1..MaxChannels] of array of TMIDINote; // The data of MIDI notes per channel
  end;
Bei IntA = 3 gibt er mir ne note von 60 anstelle von 65..
Und so geht es weiter.
Das kann es doch nicht sein.

gruss

ULIK 10. Mai 2011 05:56

AW: Debugger Krise
 
Was soll denn byte(FileInfo.MIDINotes[IntA]) sein? Du machst doch hier einen Byte-Cast eines Arrays. Bist Du sicher, daß das so in Ordnung ist?

Grüße,
Uli

EWeiss 10. Mai 2011 06:03

AW: Debugger Krise
 
Zitat:

Zitat von ULIK (Beitrag 1099890)
Was soll denn byte(FileInfo.MIDINotes[IntA]) sein? Du machst doch hier einen Byte-Cast eines Arrays. Bist Du sicher, daß das so in Ordnung ist?

Grüße,
Uli

Ohne bekomme ich den Fehler !
[DCC Fehler] uMidiTracker.pas(451): E2010 Inkompatible Typen: 'Integer' und 'Dynamic array'

NoteNo gibt ein byte zurück.
bei low kommen nicht die richtigen Daten genau so wenig bei high.

Und wenn du schaust sieht das so aus..
Delphi-Quellcode:
byte(FileInfo.MIDINotes[IntA])].NoteNo


Das ist auch seltsam warum er diese Meldung ausgibt
Zitat:

'Integer' und 'Dynamic array'
Es wird ein byte zurückgeliefert und nirgends steht was von Interger


gruss

ChrisE 10. Mai 2011 06:13

AW: Debugger Krise
 
Hallo EWeiss
Zitat:

Zitat von s.h.a.r.k (Beitrag 1099886)
Ich kenne nur ein Phenomän, wenn Delphi die for-Schleife optimiert und der Debugger nicht darauf achtet. Wobei lediglich die Darstellung falsch ist, intern aber alles korrekt abläuft.!

Hast du die Optimierung an oder aus? Und hast du nach dem "Umschalten" komplett neu erzeugt?

Gruß und guten morgen,

Chris

EWeiss 10. Mai 2011 06:18

AW: Debugger Krise
 
Zitat:

Zitat von ChrisE (Beitrag 1099893)
Hallo EWeiss
Zitat:

Zitat von s.h.a.r.k (Beitrag 1099886)
Ich kenne nur ein Phenomän, wenn Delphi die for-Schleife optimiert und der Debugger nicht darauf achtet. Wobei lediglich die Darstellung falsch ist, intern aber alles korrekt abläuft.!

Hast du die Optimierung an oder aus? Und hast du nach dem "Umschalten" komplett neu erzeugt?

Gruß und guten morgen,

Chris

Guten Morgen

Ich habe die Optimierung aus.
Vorher habe ich alle DCU's gelöscht bevor ich diese ausgeschaltet habe.

Danach komplett neu erzeugt.
Jetzt arbeite ich ja mit D2009 und mein Kumpel hat hier eine TTntFileStream deklariert über die ich aber nicht verfüge.
Wäre es möglich das hier der Wurm begraben liegt?

function GetDelta(const {$IFNDEF UNICODE} F: TTntFileStream {$ELSE} F: TFileStream{$ENDIF}; var Len: word): DWORD;
Da ich ja Unicode verwende sollte er eigentlich diesen FileStream verwenden.

Und wenn wo bekomme ich die her?
Hab da nichts gefunden beim googel.

gruss

ChrisE 10. Mai 2011 06:28

AW: Debugger Krise
 
Hallo,

ich glaube das was ULIK versucht hat klar zu machen ist, dass du oft diesen Code hier hast:
Delphi-Quellcode:
byte(FileInfo.MIDINotes[IntA])
.
Wenn man deiner Record-Deklaration vertrauen darf, dann ist aber MIDINotes ein
Delphi-Quellcode:
array[..] of array of TMIDINote
(hier ja ohne s). Wenn du dieses Record auf ein Byte "reduzierst", dann siehst du wahrscheinlich nur das erste Byte von TMIDINote.

Gruß, Chris

EWeiss 10. Mai 2011 06:30

AW: Debugger Krise
 
Zitat:

Zitat von ChrisE (Beitrag 1099899)
Hallo,

ich glaube das was ULIK versucht hat klar zu machen ist, dass du oft diesen Code hier hast:
Delphi-Quellcode:
byte(FileInfo.MIDINotes[IntA])
.
Wenn man deiner Record-Deklaration vertrauen darf, dann ist aber MIDINotes ein
Delphi-Quellcode:
array[..] of array of TMIDINote
(hier ja ohne s). Wenn du dieses Record auf ein Byte "reduzierst", dann siehst du wahrscheinlich nur das erste Byte von TMIDINote.

Gruß, Chris

Versteh aber was soll ich übergeben ?
Eine Idee?

Denn wie du gelesen hast
Zitat:

[DCC Fehler] uMidiTracker.pas(451): E2010 Inkompatible Typen: 'Integer' und 'Dynamic array'

bekomme ich einen Fehler!
Bei low Irrationale werte und bei high stürzt die Anwendung ab.

EDIT:
Schau mal oben im Thread "Bild 3" dann kannst du sehen was ich vom Debugger geliefert bekomme
Und die werte stimmen alle werden aber falsch übergeben/ausgelesen vom Compiler.


gruss

ConnorMcLeod 10. Mai 2011 06:40

AW: Debugger Krise
 
Ohne zu wissen, wie ReadMIDIFile die Struktur füllt ... mit ist aufgefallen, dass in guter alter Delphi-Manier
Delphi-Quellcode:
    for IntA := 0 to FileInfo.NoteCounter[IntI] -1 do
    begin
durchlaufen wird, aber
Delphi-Quellcode:
  for IntI := 1 to FileInfo.Tracks do
  begin
. Wenn das
Delphi-Quellcode:
  for IntI := 0 to FileInfo.Tracks-1 do
  begin
heissen sollte, dann schaust Du immer auf die falsche Note. Bzw beim letzten Schleifendurchlauf kracht's dann.

Aber wie auch immer ...
Zitat:

Zitat von EWeiss (Beitrag 1099887)
Was soll ich denn jetzt machen.. grrrr

ruhig bleiben und erstmal davon ausgehen, dass man den Fehler selbst gemacht hat.

Was, wenn Du den Code sicherst und dann wegwirfst und langsam nochmal alles von vorne machst?

ChrisE 10. Mai 2011 06:41

AW: Debugger Krise
 
Hallo EWeiss,

ich kann natürlich nicht die Semantik Deines Codes kennen - also das wie und warum soll es funktionieren. Da bin ich nicht im Code und vor allem im Problem drinne.

Ich würde aber mal Tippen, dass du eher schreiben müßtest
Delphi-Quellcode:
FileInfo.MIDINotes[IntA].NoteN
o übergeben. Aber wie gesagt, ich kenne die Logik nicht, bzw. das Ziel nicht.

Es kann ja genauso gut sein, dass du nur IntA brauchst, da du ja durch alle Tracks durch gehst (IntI) und in jedem Track durch alle Noten (IntA). Passend zu dem Aufbau des Records ist bei
Delphi-Quellcode:
MIDINotes
die erste Stelle der Track / Channel und die zweite Stelle die Note ->
Delphi-Quellcode:
FileInfo.MIDINotes[IntI, IntA]
liefert dir
Delphi-Quellcode:
TMIDINote
Nummer IntA von Track / Channel IntI.
Davon betrachtest du ja meist die NoteNo :-)

Gruß, Chris

SirThornberry 10. Mai 2011 06:43

AW: Debugger Krise
 
Aber die Meldung sagt doch schon das da was falsch ist!
Der Typ ist ein dynamisches Array aber ein Integer wird wohl erwartet? Also hast du es dir einfach gemacht und das dynamische Array auf ein Byte gecastet.
Aber wäre es nicht richtiger auf die Werte des dynamischen Arrays zu zugreifen als das Array selbst (welches ja nur ein Pointer ist) auf ein Byte zu casten?

EWeiss 10. Mai 2011 06:49

AW: Debugger Krise
 
Delphi-Quellcode:
  for IntI := 1 to FileInfo.Tracks do
  begin
Die Schleife ist schon richtig ;)
Delphi-Quellcode:
array[1..MaxChannels]
Channels sind die tracks..

gruss

EWeiss 10. Mai 2011 06:52

AW: Debugger Krise
 
Zitat:

Zitat von SirThornberry (Beitrag 1099904)
Aber die Meldung sagt doch schon das da was falsch ist!
Der Typ ist ein dynamisches Array aber ein Integer wird wohl erwartet? Also hast du es dir einfach gemacht und das dynamische Array auf ein Byte gecastet.
Aber wäre es nicht richtiger auf die Werte des dynamischen Arrays zu zugreifen als das Array selbst (welches ja nur ein Pointer ist) auf ein Byte zu casten?

Es sieht so aus das ich etwas falsch mache.
Es ist aber doch seltsam das der Tooltip mir andere werte anzeigt die
exakt stimmen nur nicht richtig ausgewertet werden.

Ich habe es auch schon als Integer versucht ist das selbe problem bzw.. auch hier stürzt
die Anwendung ab.

gruss

FredlFesl 10. Mai 2011 07:06

AW: Debugger Krise
 
Der Code unleserlich und kaum wartbar, weil u.a das DRY-Prinzip verletzt wurde.

Der 2.Index wird wiederholt kompliziert ermittelt und ist, wie Du ja weißt, falsch

Delphi-Quellcode:
midiNote := byte(FileInfo.MIDINotes[IntA]); // falsch
midiNote := FileInfo.MIDINotes[EinIndex,NocheinIndex].NoteNo; // bessser
Du solltest dich mit den Grundlagen robuster Programmierung befassen (DRY, KISS, Refactoring).

PS: Natürlich zeigt dir Delphi etwas an. Du "errechnest" ja einen Index (eigentlich beschneidest Du einen Pointer) und dann ist der Index eben irgendwas zwischen 0 und 255. Da steht dann irgendwo etwas...

Wenn dein Grid die Midinoten 1:1 anzeigen soll, dann funktioniert vielleicht das hier (falls ich den Code richtig verstanden habe).
Delphi-Quellcode:
Function TMidiTracker.EncodeMidiNote (midiNote : TMIDINote) : Integer;
begin
  Result := -1;
  if midiNote.NoteNo > 0 then
    if midiNote.Length = 12 then
      Result := (127 - midiNote.NoteNo) + basenote
    else if midiNote.Length > 12 then
      Result := 1000 + (127 - midiNote.NoteNo + basenote)
    else
      Result := midiNote.NoteNo
  else
    Result := -1;
end;

procedure TMidiTracker.ImpMidiFile(MidiFile: Widestring);
var
  FileInfo: TMIDIFileInfo;
  IntI: Integer;
  IntA: Integer;
  midiNote : TMIDINote;

begin
  if not ReadMIDIFile(MidiFile, FileInfo) then
  begin
    MessageBox(Self.Handle, 'Not a valid MIDI file.', 'Confirm', MB_OK);
    exit;
  end;

  for IntI := 1 to FileInfo.Tracks do
  begin
    for IntA := 0 to FileInfo.NoteCounter[IntI] -1 do
    begin
      midiNote := FileInfo.MIDINotes[IntI,IntA];
      Grid[IntI - 1, IntA] := EncodeMidiNote(midiNote);
      InstGrid[IntI - 1, IntA] := midiNote.Instrument;
    end;
  end;
  DrawGrid(self.Handle);
end;

EWeiss 10. Mai 2011 07:11

AW: Debugger Krise
 
Danke für deine Hilfe werde mir das mal genau anschauen.

gruss

DeddyH 10. Mai 2011 07:14

AW: Debugger Krise
 
Noch ein Tipp: um Arrays komplett zu durchlaufen empfiehlt es sich, die Funktionen Low() und High() zu verwenden, da man damit niemals über die Arraygrenzen hinaus zugreift. Dabei spielt es keine Rolle, ob es sich um ein dynamisches, statisches oder offenes Array handelt und ob es 0-indiziert ist oder nicht.

EWeiss 10. Mai 2011 07:31

AW: Debugger Krise
 
Zitat:

Zitat von DeddyH (Beitrag 1099916)
Noch ein Tipp: um Arrays komplett zu durchlaufen empfiehlt es sich, die Funktionen Low() und High() zu verwenden, da man damit niemals über die Arraygrenzen hinaus zugreift. Dabei spielt es keine Rolle, ob es sich um ein dynamisches, statisches oder offenes Array handelt und ob es 0-indiziert ist oder nicht.

Mache ich eigentlich auch nicht anders.
Aber in dem Beispiel hat es fortwährend gekracht.
Warum weiss ich ja jetzt.

Da ich nicht gern kopiere hier meine version die läuft jetzt.
Danke nochmal.

Delphi-Quellcode:
procedure TMidiTracker.ImpMidiFile(MidiFile: Widestring);
var
  FileInfo: TMIDIFileInfo;
  MidiNote: TMIDINote;
  IntI: Integer;
  IntA: Integer;
  Tempo: byte;

begin
  if not ReadMIDIFile(MidiFile, FileInfo) then
  begin
    MessageBox(Self.Handle, 'Not a valid MIDI file.', 'Confirm', MB_OK);
    exit;
  end;

  for IntI := 1 to FileInfo.Channels do
  begin
    for IntA := 0 to FileInfo.NoteCounter[IntI] -1 do
    begin
      MidiNote := FileInfo.MIDINotes[IntI, IntA];
      if MidiNote.NoteNo = 0 then
        Grid[IntI - 1, IntA] := -1;

      if MidiNote.NoteNo > 0 then
      begin

        if MidiNote.Length = 12 then
          Grid[(IntI - 1), IntA] := (127 - MidiNote.NoteNo) + basenote;

        if MidiNote.Length > 12 then
          Grid[(IntI - 1), IntA] := 1000 + (127 - MidiNote.NoteNo + basenote);
      end;

      InstGrid[(IntI - 1), IntA] := MidiNote.Instrument;
    end;
  end;
  DrawGrid(self.Handle);

  // Spielgeschwindigkeit auf default wert setzen
  Tempo := MidiNote.Velocity;
  SKAERO_SetKnobValue(SKAERO_GetMainItem(MainHandle, ID_KNOB_SPEED),
    Tempo);
  SKAERO_SetCTLText(SKAERO_GetMainItem(MainHandle, ID_SPEEDVALLABEL),
    WideString(IntToStr(Tempo)));

end;
gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz