1
votes

I found some older code for creating a midi file. In newer Delphi it gives me the cannot assign error. I am assuming a Unicode issue? But how to fix it? The error is given for these lines

    midCmd[2] := $90;
    midCmd[3] := Note;
    midCmd[4] := Velocity;

and the full procedure here if it is needed

    procedure SaveAsMidi(note: byte; FileName: string);
    const // MIDI file header
      midHdr: array[0..13]of byte =
      ($4D,$54,$68,$64, //[0..3] Always MThd
      $00,$00,$00,$06,  // [4..7] Always the same
      $00,$01,          // [8..9] Two bytes for file format
                        // $01 = synchronous multiple tracks
      $00,$01,          // [10..11] Two bytes for number of tracks
      $01,$E0);         // [12..13] Two bytes for ticks per quarter note
      // MIDI track header
      midTrk: array[0..7]of byte =
      ($4D,$54,$72,$6B, // [0..3] Always MTrk
      $00,$00,$00,$0E); // [4..7] Four bytes for track size in bytes
      // MIDI track end bytes
      midEnd: array[0..3]of byte =
      ($00,$FF,$2F,$00); // [0..3] Always the same
      // MIDI command
      midCmd: array[0..4]of byte =
      ($80,$00,          // [0..1] Two bytes for time in ticks
      $90,               // [2] Command:
                         // $90 = Note on at channel 0
                         // $80 = Note off at channel 0
      $00,$00);          // [3] Note and [4] velocity
      // Constant velocity
      Velocity=$FF;
      // Constant duration
      Time=$FF;
var  midFile: TFileStream;
begin
     // Create MIDI file
     midFile := TFileStream.Create(FileName +'.mid', fmCreate);
     with midFile do try
    // Write MIDI header
    Write(midHdr, SizeOf(midHdr));
    // Write MIDI track
    Write(midTrk, SizeOf(midTrk));
    // Write Note On
    // Play immediately = time is 0
    midCmd[2] := $90;
    midCmd[3] := Note;
    midCmd[4] := Velocity;
    Write(midCmd, SizeOf(midCmd));
    // Write Note Off
    // Separate time into two bytes
    midCmd[0] := $80 or (Time div 128 mod 128);
    midCmd[1] := $00 or (Time mod 128);
    midCmd[2] := $80;
    Write(midCmd, SizeOf(midCmd));
    // Write MIDI track end
    Write(midEnd, SizeOf(midEnd));
  finally
    midFile.Free;
  end;
end;

What syntax do I need to assign a byte $FF format to a byte array? Thanks for any help.

1
You mark midCmd as constant. Constant value cannot be changed.Zamrony P. Juhara
Thanks for the quick reply! Changing the const to a variable fixed it.Some1Else

1 Answers

6
votes

You have declared midcmd as a typed constant, and the {$WRITEABLECONST} compiler directive is (nowadays) in the default state of {$J-} (or more verbose: {$WRITEABLECONST OFF}), meaning that typed constants are not writable.

In early versions of Delphi and Object Pascal, typed constants were always writable, which may explain the code you have found on the net. Or, it might have been specifically declaring the compiler directive as {$J+} (or {$WRITEABLECONST ON}).

To use the code as is, change the directive. To keep the default directive, change the typed constant midcmd to a variable (move it to the var section).

You can read about writable typed constants in Embarcadero's documentation.