|
EWeiss
(Gast)
n/a Beiträge |
#7
Jetzt dürft ihr alle nochmal über mich und meinen Programmierstil herziehen.
Delphi-Quellcode:
Und es funktioniert 100% auch ohne Header als Record und der ganze andere Kram
unit uMidi;
interface uses Windows, Classes, SKAeroAPI, Math, SysUtils, uGlobal, uSound; var CurrentByte: Integer; DeltaTime: Integer; LastDeltaTime: Integer; TotalBytes: Integer; MidiInst: Integer; TrackDataStartByte: Integer; MidiIsDrum: BOOL; MidiDrumNum: Integer; Bytes: array[1..10000] of byte; DeltaBinArray: array[0..3] of string; DeltaTimeArray: array[0..3] of byte; DB: Integer; TempZ: Integer; function ConvertToBinary(BInput: Integer): string; procedure ExpMidiFile(MidiFile: string); implementation uses uMidiTracker; procedure MidiFileStartNote(ActiveSpur, ActiveNote: Integer); var Flip: Integer; begin if MidiIsDrum then begin Flip := MidiDrumNum; TempZ := 9; end else begin Flip := 127 - Grid[ActiveSpur, ActiveNote]; TempZ := ActiveSpur; end; // Start Noten Befehl + Channel Bytes[CurrentByte] := 144 + TempZ; inc(CurrentByte); Bytes[CurrentByte] := Flip + Basenote; // Note + Basenote inc(CurrentByte); Bytes[CurrentByte] := 127; // Geschwindigkeit inc(CurrentByte); end; procedure MidiFileStopNote(ActiveSpur: Integer); var Flip: Integer; begin if MidiIsDrum then begin Flip := MidiDrumNum; TempZ := 9; end else begin Flip := 127 - (MidiTracker.OldNote[ActiveSpur] mod 1000); TempZ := ActiveSpur; end; // Stop Noten Befehl + Channel Bytes[CurrentByte] := 128 + TempZ; inc(CurrentByte); Bytes[CurrentByte] := Flip + Basenote; // Note + Basenote inc(CurrentByte); Bytes[CurrentByte] := 0; // Geschwindigkeit inc(CurrentByte); end; procedure ConvertDeltaTime; var DB, DA, DC, DD: Integer; Temp: string; begin // 12 Delta schläge pro 16tel Note DB := DeltaTime * 12; Temp := ConvertToBinary(DB); DA := Length(Temp) mod 7; if DA <> 0 then Temp := StringOfChar('0', 7 - DA) + Temp; DD := Length(Temp) div 7 - 1; for DA := 0 to DD do begin DeltaBinArray[DA] := MidStr(Temp, DA * 7 + 1, 7); if DA = DD then DeltaBinArray[DA] := '0' + DeltaBinArray[DA] else DeltaBinArray[DA] := '1' + DeltaBinArray[DA]; end; // Konvertiere Binärzeichenfolge in DeltaBinArray zu Bytes ins DeltaTimeArray for DA := 0 to DD do begin DB := 0; for DC := 1 to 8 do begin if MidStr(DeltaBinArray[DA], DC, 1) = '1' then DB := DB + trunc(Math.Power(2, (8 - DC))); end; DeltaTimeArray[DA] := DB; end; for DA := 0 to DD do begin Bytes[CurrentByte] := DeltaTimeArray[DA]; inc(CurrentByte); end; end; procedure ConvertTempo; var DB: Integer; DA, DC: Integer; MPQN: Integer; BytesArray: array[0..2] of string; // microsekunden pro viertel Note Temp: string; begin MPQN := 60000000 div MidiTracker.Tempo; DB := MPQN; Temp := ConvertToBinary(DB); Temp := StringOfChar('0', 24 - Length(Temp)) + Temp; for DA := 0 to 2 do BytesArray[DA] := MidStr(Temp, DA * 8 + 1, 8); // Konvertiere Binärzeichenfolge in BytesArray zu Bytes for DA := 0 to 2 do begin DB := 0; for DC := 1 to 8 do begin if MidStr(BytesArray[DA], DC, 1) = '1' then DB := DB + trunc(Math.Power(2, (8 - DC))); end; Bytes[27 + DA] := DB; end; end; function ConvertToBinary(BInput: Integer): string; var Power: Integer; BTemp: string; BNum: Integer; BA, BB: Integer; begin BNum := BInput; Power := 0; while trunc(Math.Power(2, Power)) < BNum do inc(Power); dec(Power); if Power < 0 then Power := 0; BTemp := ''; for BA := Power downto 0 do begin BB := trunc(Math.Power(2, BA)); if BNum >= BB then begin BTemp := BTemp + '1'; BNum := BNum - BB; end else BTemp := BTemp + '0' end; Result := BTemp; end; procedure ConvertTrackLength; var DA, DC: Integer; TotalBytesArray: array[0..3] of string; Temp: string; begin // Ins binär formate konvertieren DB := TotalBytes; Temp := ConvertToBinary(DB); Temp := StringOfChar('0', 32 - length(Temp)) + Temp; for DA := 0 to 3 do TotalBytesArray[DA] := MidStr(Temp, DA * 8 + 1, 8); // Konvertiere Binärzeichenfolge in TotalBytesArray zu Bytes for DA := 0 to 3 do begin DB := 0; for DC := 1 to 8 do begin if MidStr(TotalBytesArray[DA], DC, 1) = '1' then DB := DB + trunc(Math.Power(2, (8 - DC))); end; Bytes[TrackDataStartByte - (4 - DA)] := DB; end; end; procedure ExpMidiFile(MidiFile: string); var IntZ: Integer; IntA: Integer; f: TFileStream; begin // MIDI File Header Chunk (14 bytes) // MTHD Bytes[1] := ord('M'); Bytes[2] := ord('T'); Bytes[3] := ord('h'); Bytes[4] := ord('d'); // Headerlänge 6 bytes Bytes[5] := 0; Bytes[6] := 0; Bytes[7] := 0; Bytes[8] := 6; // 6 byte Header // 0 - Einzelne Spur // 1 - Mehrere Spuren, Syncron // 2 - Mehrere Spuren, ASyncron Bytes[9] := 0; Bytes[10] := 1; Bytes[11] := 0; Bytes[12] := 9; // Spur Nummer Bytes[13] := 0; Bytes[14] := 48; // Anzahl der Delta-Zeit sekunde pro Viertelnote // Spur 1 // MTRK Bytes[15] := ord('M'); Bytes[16] := ord('T'); Bytes[17] := ord('r'); Bytes[18] := ord('k'); // Anzahl der Bytes in der Spur Bytes[19] := 0; Bytes[20] := 0; Bytes[21] := 0; Bytes[22] := 19; // Geschwindigkeit Bytes[23] := 0; // delta Zeit Bytes[24] := 255; // FF (Meta Befehl) Bytes[25] := 81; // Tempo Befehl Bytes[26] := 3; // 3 bytes für Tempo Beschreibung ConvertTempo; // 3 bytes fürs Tempo schreiben // Zeit Signatur Bytes[30] := 0; // delta Zeit Bytes[31] := 255; // FF (Meta Befehl) Bytes[32] := 88; // Zeit Signatur Befehl Bytes[33] := 4; // 4 bytes Bytes[34] := 4; // Zähler Bytes[35] := 2; // Nenner (2 = 1/4, 3 = 1/8, 4 = 1/16, etc.) Bytes[36] := 24; // ? Bytes[37] := 8; // 32 Note in einer 4 Note; // Spur Ende Bytes[38] := 0; // delta Zeit Bytes[39] := 255; // Spurende Befehl Bytes[40] := 47; Bytes[41] := 0; With MidiTracker do begin // Spuren schreiben CurrentByte := 41; MidiTracker.FindEndOfSong; inc(MidiTracker.SongLength); // Spuren einlesen for IntZ := 0 to 7 do begin inc(CurrentByte); OldNote[IntZ] := -1; OldInst[IntZ] := -1; LastDeltaTime := 0; TotalBytes := 0; // MTRK Bytes[CurrentByte] := ord('M'); inc(CurrentByte); Bytes[CurrentByte] := ord('T'); inc(CurrentByte); Bytes[CurrentByte] := ord('r'); inc(CurrentByte); Bytes[CurrentByte] := ord('k'); inc(CurrentByte); CurrentByte := CurrentByte + 4; TrackDataStartByte := CurrentByte; if SKAERO_GetCheckButtonStatus(SKAERO_GetMainItem(MainHandle, IntZ + ID_HIDETRACK_FIRST)) = False then begin for IntA := 0 to SongLength do begin // NotenTyp suchen if OldNote[IntZ] = -1 then OldNoteType := BlankNote; if (OldNote[IntZ] >= 0) and (OldNote[IntZ] < 1000) then OldNoteType := StartingNote; if OldNote[IntZ] >= 1000 then OldNoteType := ContinuingNote; if IntA = SongLength then begin NoteType := BlankNote; end else begin if Grid[IntZ, IntA] = -1 then NoteType := BlankNote; if (Grid[IntZ, IntA] >= 0) and (Grid[IntZ, IntA] < 1000) then NoteType := StartingNote; if Grid[IntZ, IntA] >= 1000 then NoteType := ContinuingNote; end; // Ändere das Instrument wenn nötig // wird eine neue Note gespielt und das Instrument unterscheidet sich vom alten MidiInst := (InstGrid[IntZ, IntA]); if (NoteType = StartingNote) and (MidiInst <> OldInst[IntZ]) then begin // Instrument wählen if MidiInst < 128 then begin DeltaTime := IntA - LastDeltaTime; ConvertDeltaTime; // Intrumenten Befehl + Channel Bytes[CurrentByte] := 192 + IntZ; inc(CurrentByte); Bytes[CurrentByte] := MidiInst; inc(CurrentByte); LastDeltaTime := IntA; MidiIsDrum := False; end else begin // Perkussions Instrument MidiIsDrum := True; MidiDrumNum := MidiInst - 93; end; end; //Stop die Alte Note und starte Neue if (OldNoteType <> BlankNote) and (NoteType = StartingNote) then begin // Stope die Alte Note DeltaTime := IntA - LastDeltaTime; ConvertDeltaTime; MidiFileStopNote(IntZ); // Starte neue Note Bytes[CurrentByte] := 0; // Delta zeit inc(CurrentByte); MidiFileStartNote(IntZ, IntA); LastDeltaTime := IntA; end; // Stop die Alte Note aber keine Neue if (OldNoteType <> BlankNote) and (NoteType = BlankNote) then begin DeltaTime := IntA - LastDeltaTime; ConvertDeltaTime; MidiFileStopNote(IntZ); LastDeltaTime := IntA; end; // Starte neue Note aber stoppe nicht die Alte if (OldNoteType = BlankNote) and (NoteType = StartingNote) then begin DeltaTime := IntA - LastDeltaTime; ConvertDeltaTime; MidiFileStartNote(IntZ, IntA); LastDeltaTime := IntA; end; // Setze die Alte Note als Aktuelle note OldNote[IntZ] := Grid[IntZ, IntA]; // Setze das Alte Instrument als Aktuelles if NoteType = StartingNote then OldInst[IntZ] := InstGrid[IntZ, IntA]; end; // End for IntA end; // End SKAERO_GetCheckButtonStatus // Spur ende DeltaTime := SongLength - LastDeltaTime; // Delta Zeit ConvertDeltaTime; Bytes[CurrentByte] := 255; inc(CurrentByte); Bytes[CurrentByte] := 47; inc(CurrentByte); Bytes[CurrentByte] := 0; TotalBytes := CurrentByte - TrackDataStartByte + 1; ConvertTrackLength; end; // for IntZ end; // End with MidiTracker // Datei schreiben f := TFileStream.Create(MidiFile, fmCreate or fmOpenReadWrite); f.Write(Bytes[1], CurrentByte); f.Free; end; end. der für mich in manchen Situationen uninteressant und unnötig ist. Warum eine Komponente vom 500KB in ein Projekt integrieren wenn es auch anders geht. gruss |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |