MIDI播放器尽可能精确地播放音符非常重要.我从来没有成功,总是指责计时器(参见前一个主题:如何防止提示中断计时器).最近我收购了ProDelphi并开始测量那段时间到底消耗了多少.结果非常令人惊讶,请参阅下面的示例代码.
procedure TClip_View.doMove (Sender: TObject; note, time, dure, max_time: Int32);
var x: Int32;
begin
{$IFDEF PROFILE}Profint.ProfStop; Try; Profint.ProfEnter(@self,1572 or $58B20000); {$ENDIF}
Image.Picture.Bitmap.Canvas.Pen.Mode := pmNot;
Image.Picture.Bitmap.Canvas.MoveTo (FPPos, 0);
Image.Picture.Bitmap.Canvas.LineTo (FPPos, Image.Height);
x := time * GPF.PpM div MIDI_Resolution;
Image.Picture.Bitmap.Canvas.Pen.Mode := pmNot;
Image.Picture.Bitmap.Canvas.MoveTo (x, 0);
Image.Picture.Bitmap.Canvas.LineTo (x, Image.Height);
FPPos := x;
// Bevel.Left := time * GPF.PpM div MIDI_Resolution;
{$IFDEF PROFILE}finally; Profint.ProfExit(1572); end;{$ENDIF}
end; // doMove //
Run Code Online (Sandbox Code Playgroud)
测量结果是(在Intel i7-920上没有调试代码,2,7Ghz):
Bevel.Left :=)x := time * GPF.PpM div MIDI_Resolution;只需在Bevel上移动就需要花费60倍于绘制Canvas的CPU.这让我感到惊讶.测量1的结果非常可听(除此之外还有更多),但不是2和3.我需要某种形式的反馈给用户,因为玩家现在正在处理,钢琴卷上的某种线是可接受的方式.在我永远不断寻求减少定时事件循环中的CPU周期时,我有一些问题:
Arn*_*hez 10
你将无法改变世界,也无法改变VCL和Windows.我怀疑你对那些要求很多......
恕我直言,你应该更好地改变你的架构:
也就是说,序列发生器不会刷新UI,但UI会定期询问序列器的当前状态.这将是恕我直言,更顺畅.
要回答您的确切问题:
DoubleBuffered := true使用TForm.OnCreate事件,或者使用TPaintBox带有全局位图的专用component()来获取整个组件内容,类似于消息WM_ERASEBKGND.一些代码:
procedure TMyPaintBox.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
Message.Result := 1; // no erasing is necessary after this method call
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
762 次 |
| 最近记录: |