英文:
How to accurately change tempo for playing midi files of all resolutions?
问题
我有一个Java Swing中的MIDI编辑器应用程序,可以播放加载的音乐。分辨率(每四分音符的刻度数)可以从24到1000不等,而大多数MIDI文件都在较高范围内。我实现了一个功能,用户可以设置每分钟四分之一拍的播放速度。程序通过计算使用Swing定时器延迟来改变播放速度,公式如下:
其中BPM和resolution是变量。基本上,这个函数看起来就像是y = 1/x,固定BPM的一个值。然而,Swing定时器的延迟是以毫秒为单位的整数值。对于较高的分辨率,由于函数的性质,延迟始终会四舍五入为1,而不考虑BPM。
在播放音乐时,有什么最佳解决方案可以实现大致准确的速度?我是否需要使用更快的定时器?如果是这样,有哪些选项?我是否应该编写一些逻辑,在每次定时器触发时向前移动x个MIDI刻度,而不是1个,以解决Swing定时器的限制?
英文:
I have a midi editor app in Java swing that can play back the loaded music. The resolution (ticks per quarter note value) can vary from 24 to 1000, with most midi files being in the higher range. I implemented a feature where the user can set the playback tempo in quarter beats per minute. The program varies the speed of the playback by calculating the Swing timer delay using
where BPM and resolution are the variables. Basically, the function just looks like y = 1/x, fixing a value for BPM. However, the Swing timer delay is an int value in milliseconds. For higher resolutions, the delay always rounds to 1 regardless of the BPM due to the nature of the function.
What is the best solution so that I can play back the music at a roughly accurate speed? Would I need to just use a faster timer? If so, what are the options? Should I write some logic that moves forward x midi ticks every timer tick instead of 1 to work around the Swing timer's limitations?
答案1
得分: 1
舍入误差会累积。由于代码执行而导致的延迟也会累积。
因此:
- 将时间戳计算为浮点数(这样单个时间戳可能会偏差约 ±0.5 毫秒,但时间间隔的总和不会更糟);
- 计算每个事件的绝对时间,并设置定时器,使其在
目标时间 - 当前时间
毫秒后触发,无论具体时间为何。
英文:
Rounding errors will add up. And delays due to execution of your code will add up.
Therefore:
- compute timestamps as floating-point values (so that individual timestamps might be off by ± 0.5 ms, but that the sum of time intervals is no worse); and
- compute the absolute time of each event, and set the timer so that it elapses in
target_time - current_time
milliseconds, whatever that may be.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论