Я создаю простое приложение MacOS для воспроизведения аудио в swift.У меня есть форма волны, нарисованная на экране (используя https://github.com/benoit-pereira-da-silva/SoundWaveForm) вместе с линиями сетки для каждого столбца / меры (серые линии) и линиями сетки для каждой четвертной ноты (красные линии). См. Изображение в конце сообщения.
Продолжительность 1 бара и общее количество баров в аудиофайле рассчитывается следующим образом:
let quantify1Bar = (60000 / BPM) * 4 // Milliseconds per bar
let totalBars = totalAudioDuration * 1000 / quantify1Bar
Затем я вычисляю расстояние в пикселях между линиями сетки:
let pxSpacing1Bar = (pxTimelineWidth / totalBars) * zoomLevel
let pxSpacingQuarter = (pxTimelineWidth / totalBars) * zoomLevel
pxTimelineWidth - 1560 пикселей
Моя переменная zoomLevel просто делится или умножается при нажатии кнопок «-» и «+» (т. Е. Если zoomLevel равен 1, вы видите полную продолжительностьформа звукового сигнала ... если zoomLevel равен 2, вы видите половину длины звука ... 4 = четверть длины и т. д .:
zoomLevel = zoomLevel / 2 (zoom out)
zoomLevel = zoomLevel * 2 (zoom in)
Я рисую линии сетки следующим образом:
let pathBar = NSBezierPath()
let pathQuarter = NSBezierPath()
// Draw lines for every bar
for i in 0...totalBarLines {
pathBar.move(to: NSPoint(x: i * pxSpacing1Bar, y: 0))
pathBar.line(to: NSPoint(x: i * pxSpacing1Bar, y: 100))
pathBar.lineWidth = 1
NSColor.darkGray.setFill()
NSColor.darkGray.setStroke()
pathBar.stroke()
}
// Draw 1/4 note lines
for i in 0...totalQuarterLines {
if i == 0 {
// Do nothing - skip the first line of every bar
} else if i % 4 != 0 {
pathQuarter.move(to: NSPoint(x: i * pxSpacingQuarter, y: 10))
pathQuarter.line(to: NSPoint(x: i * pxSpacingQuarter, y: 90))
pathQuarter.lineWidth = 1
NSColor.red.setFill()
NSColor.red.setStroke()
pathQuarter.stroke()
}
}
Моя проблема в том, что на более высоких уровнях масштабирования линии сетки имеют заметный дрейф даже в течение короткого периода времени, и каждый дрейф больше, чем предыдущий дрейф (см. Изображение). Это кажется достаточно простым,моя переменная zoomLevelВы вызываете это во время прорисовки линий сетки?
AudioGridLines