亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? midifile.pas

?? Delphi鋼琴源碼
?? PAS
字號:
{
  Load a midifile and get access to tracks and events
  I did build this component to convert midifiles to wave files
  or play the files on a software synthesizer which I'm currenly
  building.

  version 1.3
  F.Bouwmans
  fbouwmans@spiditel.nl

  version 1.4
  Z.wan
  ziziiwan@hotmail.com
}

unit MidiFile;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs, MMSystem,
  StdCtrls, ExtCtrls, Math;

type
  TChunkType = (ctIllegal, ctHeader, ctTrack);
  TFileType = (ftSingle, ftMultiSynch, ftMultiAsynch);
  TChannels = array[0..15] of Boolean;

  TMidiEvent = record
    iTrack: Byte;
    iEvent: Byte;
    iData1: Byte;
    iData2: Byte;
    sLetter: string;
    iPulses: Integer;
    iPositon: Integer;
    iSize: Integer;
  end;
  PMidiEvent = ^TMidiEvent;

  TMidiHead = record
    FileType: TFileType;
    NumberTracks: Integer;
    PulsesPerQuarter: Integer;
  end;
  PMidiHead = ^TMidiHead;

  TMidiTrack = class(TObject)
  private
    FActive: Boolean;
    FReady: Boolean;
    FEventList: TList;
    FTrackName: string;
    FTrackKeyword: string;
    FTrackCopyright: string;
    FChannels: TChannels;
    FInstrument: string;
    FPosition: Integer;
    FTime: Integer;
    FTrackSize: Integer;
    procedure CalaculateSize;
  protected
    function GetEventCount: Integer;
    function GetTrackLength: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure AddEvent(Event: PMidiEvent);
    function GetEvent(Index: Integer): PMidiEvent;
    function GetChannels(Index: Integer): Boolean;
  published
    property Active: Boolean read FActive write FActive;
    property Ready: Boolean read FReady write FReady;
    property Position: Integer read FPosition write FPosition;
    property Time: Integer read FTime write FTime;
    property TrackName: string read FTrackName;
    property EventCount: Integer read GetEventCount;
    property TrackLength: Integer read GetTrackLength;
  end;

  TMidiFile = class(TComponent)
  private
    FFileName: string;
    FMidiFile: file of Byte;
    FChunkType: TChunkType;
    FChunkLength: Integer;
    FChunkData: PByte;
    FChunkIndex: PByte;
    FChunkEnd: PByte;
    FMidiHead: TMidiHead;
    FMidiTrack: TMidiTrack;
    FTrackList: TList;
    procedure ReadChunkHeader;
    procedure ReadChunkContent;
    procedure ProcessHeaderChunk;
    procedure ProcessTrackChunk;
    procedure WriteChunkHeader;
    procedure WriteChunkContent;
    procedure RecordHeaderChunk;
    procedure RecordTrackChunk;
    procedure SetFileName(const Value: string);
    function GetMidiLength: Integer;
    function GetTrackCount: Integer;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure ReadFile;
    procedure WriteFile;
    procedure SetMidiHead(const Value: TMidiHead);
    function GetMidiHead: TMidiHead;
    procedure SetTrackList(const Value: TList);
    function GetTrackList: TList;
    procedure SetTrack(const Value: TMidiTrack);
    function GetTrack(Index: Integer): TMidiTrack;
  published
    property FileName: string read FFileName write SetFileName;
    //property MidiHead: TMidiHead read FMidiHead write SetMidiHead;
    //property MidiTrack: TMidiTrack read FMidiTrack write SetTrack;
    property MidiLength: Integer read GetMidiLength;
    property TrackCount: Integer read GetTrackCount;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Piano Suite', [TMidiFile]);
end;

{ Common }

procedure WriteVarLength(Value: LongInt; Mask: Byte; var PIndex: PByte);
var
  b: byte;
  i: Longint;
begin
  b := Value and $7F;
  i := Value shr 7;
  if i > 0 then
    WriteVarLength(i, $80, PIndex);
  b := b or mask;
  PIndex^ := b;
  Inc(PIndex);
end;

procedure WriteString(Value: string; var PIndex: PByte);
var
  i: Integer;
  Len: Integer;
begin
  Len := Length(Value);
  for i := 1 to Len do
  begin
    PIndex^ := Ord(Value[i]);
    inc(PIndex);
  end;
end;

function ReadVarLength(var PIndex: PByte): Integer;
var
  i: integer;
  b: byte;
begin
  b := $80;
  i := $0;
  while b > $7F do
  begin
    i := i shl 7;
    b := PIndex^;
    i := i + b and $7F;
    Inc(PIndex);
  end;
  Result := i;
end;

function ReadString(Len: Integer; var PIndex: PByte): string;
var
  c: PChar;
  i: Integer;
begin
  GetMem(C, Len + 1); ;
  c[Len] := Chr(0);
  for i := 0 to Len - 1 do
  begin
    c[i] := Chr(PIndex^);
    inc(PIndex);
  end;
  Result := string(c);
end;

procedure LengthToByte(Value: Integer; var b1, b2, b3, b4: Byte);
begin
  b1 := Value div $1000000;
  b2 := Value div $10000;
  b3 := Value div $100;
  b4 := Value;
end;

procedure ByteToLength(b1, b2, b3, b4: Byte; var Value: Integer);
begin
  Value := b4 + b3 * $100 + b2 * $10000 + b1 * $1000000;
end;

{ TMidiTrack }

constructor TMidiTrack.Create;
var
  i: Integer;
begin
  inherited Create;
  FEventList := TList.Create;
  FActive := True;
  FReady := False;
  FTrackName := '';
  FTrackKeyword := '';
  FTrackCopyright := '';
  for i := 0 to 15 do
    FChannels[i] := False;
  FInstrument := '';
  FPosition := 0;
  FTime := 0;
  FTrackSize := 0;
end;

destructor TMidiTrack.Destroy;
var
  i: integer;
begin
  for i := 0 to FEventList.Count - 1 do
    Dispose(PMidiEvent(FEventList[i]));
  FEventList.Free;
  inherited;
end;

procedure TMidiTrack.AddEvent(Event: PMidiEvent);
begin
  if (Event^.iEvent = $FF) then
  begin
    case Event^.iData1 of
      $1: FTrackKeyword := FTrackKeyword + Event^.sLetter;
      $2: FTrackCopyright := FTrackCopyright + Event^.sLetter;
      $3: FTrackName := FTrackName + Event^.sLetter;
      $4: FInstrument := FInstrument + Event^.sLetter;
    end;
  end else
  begin
    case Event^.iEvent of
      $B0..$BF, $C0..$CF: // control change, program change
        FChannels[Event^.iEvent and $F] := True;
    end;
  end;
  FPosition := FPosition + Event^.iPulses;
  Event^.iPositon := FPosition;
  FEventList.Add(Event);
end;

function TMidiTrack.GetEvent(Index: Integer): PMidiEvent;
begin
  if (Index >= 0) and (Index < FEventList.Count) then
    Result := PMidiEvent(FEventList[Index]) else
    Result := nil;
end;

function TMidiTrack.GetEventCount: Integer;
begin
  Result := FEventList.Count;
end;

function TMidiTrack.GetTrackLength: Integer;
begin
  Result := PMidiEvent(FEventList[FEventList.Count - 1]).iPositon;
end;

function TMidiTrack.GetChannels(Index: Integer): Boolean;
begin
  Result := FChannels[Index];
end;

procedure TMidiTrack.CalaculateSize;
var
  i: Integer;
begin
  FTrackSize := 0;
  for i := 0 to GetEventCount - 1 do
  begin
    Inc(FTrackSize, GetEvent(i)^.iSize);
  end;
end;

{ TMidiFile }

constructor TMidiFile.Create(AOwner: TComponent);
begin
  inherited Create(AOWner);

  FChunkType := ctIllegal;
  FChunkLength := -1;
  FChunkData := nil;
  FChunkIndex := nil;
  FChunkEnd := nil;

  FTrackList := TList.Create;
end;

destructor TMidiFile.Destroy;
var
  i: Integer;
begin
  if not (FChunkData = nil) then
    FreeMem(FChunkData);

  for i := 0 to GetTrackCount - 1 do
    TMidiTrack(FTrackList[i]).Free;
  FTrackList.Free;

  inherited;
end;

procedure TMidiFile.SetTrack(const Value: TMidiTrack);
begin
  FMidiTrack := Value;
end;

function TMidiFile.GetTrack(Index: Integer): TMidiTrack;
begin
  if (Index >= 0) and (Index < FTrackList.Count) then
    Result := TMidiTrack(FTrackList[Index]) else
    Result := nil;
end;

procedure TMidiFile.WriteChunkHeader;
var
  tmpByte: array[0..7] of Byte;
begin
  if FChunkType = ctHeader then
  begin
    tmpByte[0] := $4D; //M
    tmpByte[1] := $54; //T
    tmpByte[2] := $68; //h
    tmpByte[3] := $64; //d
  end;
  if FChunkType = ctTrack then
  begin
    tmpByte[0] := $4D; //M
    tmpByte[1] := $54; //T
    tmpByte[2] := $72; //r
    tmpByte[3] := $6B; //k
  end;
  LengthToByte(FChunkLength, tmpByte[4], tmpByte[5], tmpByte[6], tmpByte[7]);
  BlockWrite(FMidiFile, tmpByte, 8);
end;

procedure TMidiFile.ReadChunkHeader;
var
  tmpByte: array[0..7] of Byte;
begin
  FChunkType := ctIllegal;
  FChunkLength := -1;
  // read "4D 54 68 64", follow "00 00 00 06", Head
  // read "4D 54 72 6B", follow "00 00 0C DF", Track
  BlockRead(FMidiFile, tmpByte, 8);
  if (tmpByte[0] = $4D) and (tmpByte[1] = $54) then // MT
  begin
    if (tmpByte[2] = $68) and (tmpByte[3] = $64) then // hd, mean header
      FChunkType := ctHeader;
    if (tmpByte[2] = $72) and (tmpByte[3] = $6B) then // rk, mean track
      FChunkType := ctTrack;
  end;
  if FChunkType <> ctIllegal then
    ByteToLength(tmpByte[4], tmpByte[5], tmpByte[6], tmpByte[7], FChunkLength)
end;

procedure TMidiFile.WriteChunkContent;
begin
  if not (FChunkData = nil) then
    FreeMem(FChunkData);
  GetMem(FChunkData, FChunkLength + 1);
  FChunkIndex := FChunkData;
  FChunkEnd := PByte(Integer(FChunkIndex) + Integer(FChunkLength) - 1);
//  BlockWrite(FMidiFile, FChunkData^, FChunkLength);
end;

procedure TMidiFile.ReadChunkContent;
begin
  if not (FChunkData = nil) then
    FreeMem(FChunkData);
  GetMem(FChunkData, FChunkLength + 1);
  BlockRead(FMidiFile, FChunkData^, FChunkLength);
  FChunkIndex := FChunkData;
  FChunkEnd := PByte(Integer(FChunkIndex) + Integer(FChunkLength) - 1);
end;

procedure TMidiFile.RecordHeaderChunk;
begin
  FChunkType := ctHeader;
  FChunkLength := 6;
  WriteChunkHeader; // 4D 54 68 64 00 00 00 06
  WriteChunkContent;
  // ff ff, FileType
  FChunkIndex^ := 0;
  Inc(FChunkIndex);
  FChunkIndex^ := Integer(FMidiHead.FileType);
  // nn nn, NumberTracks
  Inc(FChunkIndex);
  FChunkIndex^ := FMidiHead.NumberTracks div $100;
  Inc(FChunkIndex);
  FChunkIndex^ := FMidiHead.NumberTracks;
  // dd dd, PulsesPerQuarter
  Inc(FChunkIndex);
  FChunkIndex^ := FMidiHead.PulsesPerQuarter div $100;
  Inc(FChunkIndex);
  FChunkIndex^ := FMidiHead.PulsesPerQuarter;

  BlockWrite(FMidiFile, FChunkData^, FChunkLength);
end;

procedure TMidiFile.ProcessHeaderChunk;
var
  i: Integer;
begin
  ReadChunkHeader;
  if FChunkType <> ctHeader then
    raise Exception.Create('Invalid midi format!');
  ReadChunkContent;

//  4D 54 68 64 00 00 00 06 ff ff nn nn dd dd
//
//

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产专区综合网| 亚洲精品菠萝久久久久久久| 国产欧美日本一区视频| 国产精品久久久久久久裸模| 亚洲综合精品自拍| 麻豆专区一区二区三区四区五区| 国产剧情一区在线| 在线免费观看成人短视频| 欧美一级理论片| 国产精品传媒入口麻豆| 五月激情六月综合| 国产高清不卡二三区| 欧洲国内综合视频| 久久久精品tv| 婷婷久久综合九色综合伊人色| 国产大片一区二区| 欧美日韩国产大片| 亚洲国产高清在线| 蜜桃视频在线观看一区| 91在线看国产| 精品黑人一区二区三区久久| 亚洲欧洲精品天堂一级| 蜜桃视频一区二区三区在线观看| 97久久超碰精品国产| 精品国产乱码久久久久久久| 亚洲激情自拍偷拍| 国产精品1024久久| 欧美疯狂性受xxxxx喷水图片| 国产精品女主播在线观看| 美女视频黄免费的久久 | 欧美精品 国产精品| 国产亚洲综合在线| 视频一区视频二区中文字幕| 菠萝蜜视频在线观看一区| 91精品国产乱码| 亚洲久草在线视频| 国产原创一区二区三区| 欧美日韩大陆在线| 国产一区二区三区观看| 91美女视频网站| 国产午夜亚洲精品不卡| 久久精品99久久久| 欧美日韩精品一区二区| 亚洲人成小说网站色在线| 国产高清不卡一区| 欧美精品一区二区三区视频| 日韩精品成人一区二区三区 | 一区二区中文视频| 国产美女在线观看一区| 欧美大片拔萝卜| 日韩黄色免费网站| 欧美亚男人的天堂| 亚洲精品日韩专区silk| 97精品视频在线观看自产线路二| 国产欧美一区二区在线观看| 国产资源在线一区| 精品国产一二三区| 麻豆国产精品777777在线| 欧美高清精品3d| 视频一区欧美精品| 欧美日本在线视频| 亚洲mv在线观看| 欧美日韩一区不卡| 亚洲国产精品嫩草影院| 欧美在线你懂的| 亚洲一区欧美一区| 欧美日韩一区二区在线视频| 亚洲永久免费av| 欧美日韩一区成人| 日本亚洲免费观看| 91精品国产91久久久久久一区二区| 亚洲一级电影视频| 欧美美女黄视频| 美洲天堂一区二卡三卡四卡视频| 91精品免费在线观看| 日本美女一区二区三区视频| 欧美一区二区久久| 久久aⅴ国产欧美74aaa| 精品成人一区二区三区| 国产一区二区三区四区在线观看| 久久精品亚洲精品国产欧美kt∨ | 久久久亚洲精品石原莉奈 | 国产精品伦一区二区三级视频| 国产v日产∨综合v精品视频| 欧美国产一区二区在线观看| 成人国产精品免费网站| 亚洲免费大片在线观看| 国产亚洲精久久久久久| 成人激情动漫在线观看| 成人欧美一区二区三区白人 | 亚洲欧洲精品天堂一级| 91精品福利视频| 天堂久久一区二区三区| 日韩精品自拍偷拍| 国产精品一卡二| 亚洲欧洲另类国产综合| 欧美猛男超大videosgay| 青青草97国产精品免费观看无弹窗版| 欧美白人最猛性xxxxx69交| 国产成人午夜精品影院观看视频| 亚洲欧洲韩国日本视频| 8v天堂国产在线一区二区| 久久电影网电视剧免费观看| 国产欧美一区二区精品久导航| 99国产麻豆精品| 日韩国产欧美一区二区三区| 久久久综合精品| 91免费视频大全| 日韩国产欧美在线播放| 国产亚洲成av人在线观看导航| 99久久99久久综合| 秋霞电影网一区二区| 欧美国产精品久久| 欧美日韩国产中文| 国产成人精品1024| 亚洲v中文字幕| 欧美国产精品一区二区| 欧美猛男gaygay网站| 国产91高潮流白浆在线麻豆| 亚洲图片欧美综合| 国产丝袜美腿一区二区三区| 欧美唯美清纯偷拍| 国产精品原创巨作av| 亚洲成人www| 国产精品国产a级| 日韩一区二区三区四区| 色综合中文综合网| 亚洲精品免费在线观看| 91精品午夜视频| 91麻豆国产福利精品| 韩国一区二区在线观看| 一区二区三区精品视频在线| 精品国产精品网麻豆系列| 欧美性生活大片视频| 成人一区二区视频| 蜜臀va亚洲va欧美va天堂| 亚洲欧美日韩国产一区二区三区| 精品国产免费视频| 欧美久久一二区| 91一区二区在线观看| 美女精品一区二区| 一区二区三区中文字幕| 久久久精品2019中文字幕之3| 欧美精品99久久久**| 色视频成人在线观看免| 国产成人精品免费在线| 青青草国产精品亚洲专区无| 亚洲精品午夜久久久| 欧美激情中文字幕| 日韩精品一区二区三区视频| 欧美美女一区二区三区| 色先锋aa成人| 99re在线精品| 成人中文字幕电影| 国产福利一区二区三区| 久久国产人妖系列| 日韩精品国产精品| 亚洲一区免费观看| 日韩一区中文字幕| 国产精品国产三级国产aⅴ中文 | 国产99久久久国产精品潘金网站| 免费在线欧美视频| 色狠狠综合天天综合综合| 国产成人精品亚洲日本在线桃色| 美美哒免费高清在线观看视频一区二区| 亚洲蜜臀av乱码久久精品蜜桃| 欧美国产日韩精品免费观看| 久久亚洲捆绑美女| 亚洲精品在线网站| 精品国产欧美一区二区| 精品久久久久久久久久久久久久久久久 | 欧美在线视频日韩| 日本韩国精品在线| 一本久道中文字幕精品亚洲嫩 | 亚洲精品日韩一| 依依成人精品视频| 亚洲日本va午夜在线电影| 国产日韩精品一区二区浪潮av| 欧美成人精品二区三区99精品| 欧美丝袜丝交足nylons图片| 91黄视频在线观看| 在线影视一区二区三区| 在线观看一区不卡| 欧美日韩第一区日日骚| 欧美日韩夫妻久久| 日韩午夜在线观看| 日韩精品专区在线影院重磅| 日韩亚洲欧美在线观看| 欧美一级片在线| 精品久久99ma| 国产三级精品在线| 国产精品久久免费看| 亚洲欧美偷拍三级| 亚洲国产精品嫩草影院| 日日嗨av一区二区三区四区| 蜜臀a∨国产成人精品| 国产一区在线看| www.日韩在线| 91国偷自产一区二区三区成为亚洲经典 | 欧美成人高清电影在线|