From a4ab12207288b6a4db489ab27d8a42a3d26ffcce Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:02:40 +0100 Subject: [PATCH 01/12] feat(platform): add Int8Array and complete Int16Array/Uint16Array in C# and Kotlin Adds an Int8Array runtime type to the C# and Kotlin ports and gives Int16Array/Uint16Array the same fill/subarray/set surface as Int32Array. The transpiler no longer rejects Int8Array and strips its type arguments like the other typed arrays. --- .../AlphaTab/Core/EcmaScript/Int16Array.cs | 52 +++++++++++-- .../src/AlphaTab/Core/EcmaScript/Int8Array.cs | 75 +++++++++++++++++++ .../AlphaTab/Core/EcmaScript/Uint16Array.cs | 54 +++++++++++-- .../alphaTab/core/ecmaScript/Int16Array.kt | 53 ++++++++++--- .../alphaTab/core/ecmaScript/Int8Array.kt | 71 ++++++++++++++++++ .../alphaTab/core/ecmaScript/Uint16Array.kt | 54 ++++++++++--- packages/transpiler/src/TypeResolver.ts | 9 +-- .../test/fixtures/errors/int8array/errors.txt | 2 - .../test/fixtures/errors/int8array/input.ts | 6 -- .../fixtures/types/typed-arrays/expected.cs | 33 ++++++++ .../fixtures/types/typed-arrays/expected.kt | 21 ++++++ .../test/fixtures/types/typed-arrays/input.ts | 13 ++++ 12 files changed, 396 insertions(+), 47 deletions(-) create mode 100644 packages/csharp/src/AlphaTab/Core/EcmaScript/Int8Array.cs create mode 100644 packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int8Array.kt delete mode 100644 packages/transpiler/test/fixtures/errors/int8array/errors.txt delete mode 100644 packages/transpiler/test/fixtures/errors/int8array/input.ts diff --git a/packages/csharp/src/AlphaTab/Core/EcmaScript/Int16Array.cs b/packages/csharp/src/AlphaTab/Core/EcmaScript/Int16Array.cs index 0a018555fc..c85f74ab4b 100644 --- a/packages/csharp/src/AlphaTab/Core/EcmaScript/Int16Array.cs +++ b/packages/csharp/src/AlphaTab/Core/EcmaScript/Int16Array.cs @@ -1,26 +1,66 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; namespace AlphaTab.Core.EcmaScript; internal class Int16Array : IEnumerable { - private readonly short[] _data; + private readonly ArraySegment _data; - public double Length => _data.Length; + public double Length => _data.Count; public Int16Array(double size) { - _data = new short[(int)size]; + _data = new ArraySegment(new short[(int)size]); + } + + public Int16Array(IEnumerable list) + { + _data = new ArraySegment(list.Select(i => (short)i).ToArray()); + } + + private Int16Array(ArraySegment data) + { + _data = data; } public double this[double index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data[(int)index]; + get => _data.Array![_data.Offset + (int)index]; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => _data[(int)index] = (short)value; + set => _data.Array![_data.Offset + (int)index] = (short)value; + } + + public void Fill(double value) + { + if (value == 0) + { + System.Array.Clear(_data.Array!, _data.Offset, _data.Count); + } + else + { + var v = (short)value; + for (var i = 0; i < _data.Count; i++) + { + _data.Array![_data.Offset + i] = v; + } + } + } + + public Int16Array Subarray(double start, double end) + { + return new Int16Array(new ArraySegment(_data.Array!, _data.Offset + (int)start, + (int)end - (int)start)); + } + + public void Set(Int16Array subarray, double offset) + { + System.Array.Copy(subarray._data.Array!, subarray._data.Offset, _data.Array!, + _data.Offset + (int)offset, subarray._data.Count); } public IEnumerator GetEnumerator() diff --git a/packages/csharp/src/AlphaTab/Core/EcmaScript/Int8Array.cs b/packages/csharp/src/AlphaTab/Core/EcmaScript/Int8Array.cs new file mode 100644 index 0000000000..3df12336d5 --- /dev/null +++ b/packages/csharp/src/AlphaTab/Core/EcmaScript/Int8Array.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace AlphaTab.Core.EcmaScript; + +internal class Int8Array : IEnumerable +{ + private readonly ArraySegment _data; + + public double Length => _data.Count; + + public Int8Array(double size) + { + _data = new ArraySegment(new sbyte[(int)size]); + } + + public Int8Array(IEnumerable list) + { + _data = new ArraySegment(list.Select(i => (sbyte)i).ToArray()); + } + + private Int8Array(ArraySegment data) + { + _data = data; + } + + public double this[double index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _data.Array![_data.Offset + (int)index]; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => _data.Array![_data.Offset + (int)index] = (sbyte)value; + } + + public void Fill(double value) + { + if (value == 0) + { + System.Array.Clear(_data.Array!, _data.Offset, _data.Count); + } + else + { + var v = (sbyte)value; + for (var i = 0; i < _data.Count; i++) + { + _data.Array![_data.Offset + i] = v; + } + } + } + + public Int8Array Subarray(double start, double end) + { + return new Int8Array(new ArraySegment(_data.Array!, _data.Offset + (int)start, + (int)end - (int)start)); + } + + public void Set(Int8Array subarray, double offset) + { + System.Array.Copy(subarray._data.Array!, subarray._data.Offset, _data.Array!, + _data.Offset + (int)offset, subarray._data.Count); + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)_data).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} diff --git a/packages/csharp/src/AlphaTab/Core/EcmaScript/Uint16Array.cs b/packages/csharp/src/AlphaTab/Core/EcmaScript/Uint16Array.cs index 7ab2db3b62..d3b9e9ebcd 100644 --- a/packages/csharp/src/AlphaTab/Core/EcmaScript/Uint16Array.cs +++ b/packages/csharp/src/AlphaTab/Core/EcmaScript/Uint16Array.cs @@ -1,26 +1,66 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; namespace AlphaTab.Core.EcmaScript; internal class Uint16Array : IEnumerable { - private readonly ushort[] _data; + private readonly ArraySegment _data; - public double Length => _data.Length; + public double Length => _data.Count; public Uint16Array(double size) { - _data = new ushort[(int) size]; + _data = new ArraySegment(new ushort[(int)size]); + } + + public Uint16Array(IEnumerable list) + { + _data = new ArraySegment(list.Select(i => (ushort)i).ToArray()); + } + + private Uint16Array(ArraySegment data) + { + _data = data; } public double this[double index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _data[(int) index]; + get => _data.Array![_data.Offset + (int)index]; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => _data[(int) index] = (ushort) value; + set => _data.Array![_data.Offset + (int)index] = (ushort)value; + } + + public void Fill(double value) + { + if (value == 0) + { + System.Array.Clear(_data.Array!, _data.Offset, _data.Count); + } + else + { + var v = (ushort)value; + for (var i = 0; i < _data.Count; i++) + { + _data.Array![_data.Offset + i] = v; + } + } + } + + public Uint16Array Subarray(double start, double end) + { + return new Uint16Array(new ArraySegment(_data.Array!, _data.Offset + (int)start, + (int)end - (int)start)); + } + + public void Set(Uint16Array subarray, double offset) + { + System.Array.Copy(subarray._data.Array!, subarray._data.Offset, _data.Array!, + _data.Offset + (int)offset, subarray._data.Count); } public IEnumerator GetEnumerator() @@ -32,4 +72,4 @@ IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } -} \ No newline at end of file +} diff --git a/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int16Array.kt b/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int16Array.kt index 57d05fe2bd..b740055133 100644 --- a/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int16Array.kt +++ b/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int16Array.kt @@ -1,17 +1,31 @@ package alphaTab.core.ecmaScript -import alphaTab.core.byteLength - @Suppress("NOTHING_TO_INLINE") -@ExperimentalUnsignedTypes internal class Int16Array : Iterable { private val _data: ShortArray - + private val _offset: Int public val length: Double - get() = _data.size.toDouble() public constructor(size: Double) { _data = ShortArray(size.toInt()) + _offset = 0 + length = size + } + + public constructor(values: Iterable) { + val list = values.toList() + _data = ShortArray(list.size) + for (i in list.indices) { + _data[i] = list[i].toInt().toShort() + } + _offset = 0 + length = list.size.toDouble() + } + + private constructor(data: ShortArray, offset: Int, length: Int) { + _data = data + _offset = offset + this.length = length.toDouble() } public inline operator fun get(index: Double): Double { @@ -23,14 +37,35 @@ internal class Int16Array : Iterable { } public inline operator fun get(index: Int): Double { - return _data[index].toDouble() + return _data[_offset + index].toDouble() } public inline operator fun set(index: Int, value: Double) { - _data[index] = value.toInt().toShort() + _data[_offset + index] = value.toInt().toShort() + } + + public fun fill(value: Double) { + _data.fill(value.toInt().toShort(), _offset, _offset + length.toInt()) + } + + public fun subarray(start: Double, end: Double): Int16Array { + return Int16Array(_data, _offset + start.toInt(), (end - start).toInt()) + } + + public fun set(values: Int16Array, offset: Double) { + values._data.copyInto( + _data, + _offset + offset.toInt(), + values._offset, + values._offset + values.length.toInt() + ) } - override fun iterator(): ShortIterator { - return _data.iterator() + override fun iterator(): Iterator { + return object : Iterator { + private var _index = 0 + override fun hasNext(): Boolean = _index < length.toInt() + override fun next(): Short = _data[_offset + _index++] + } } } diff --git a/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int8Array.kt b/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int8Array.kt new file mode 100644 index 0000000000..c9471e6f72 --- /dev/null +++ b/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Int8Array.kt @@ -0,0 +1,71 @@ +package alphaTab.core.ecmaScript + +@Suppress("NOTHING_TO_INLINE") +internal class Int8Array : Iterable { + private val _data: ByteArray + private val _offset: Int + public val length: Double + + public constructor(size: Double) { + _data = ByteArray(size.toInt()) + _offset = 0 + length = size + } + + public constructor(values: Iterable) { + val list = values.toList() + _data = ByteArray(list.size) + for (i in list.indices) { + _data[i] = list[i].toInt().toByte() + } + _offset = 0 + length = list.size.toDouble() + } + + private constructor(data: ByteArray, offset: Int, length: Int) { + _data = data + _offset = offset + this.length = length.toDouble() + } + + public inline operator fun get(index: Double): Double { + return get(index.toInt()) + } + + public inline operator fun set(index: Double, value: Double) { + set(index.toInt(), value) + } + + public inline operator fun get(index: Int): Double { + return _data[_offset + index].toDouble() + } + + public inline operator fun set(index: Int, value: Double) { + _data[_offset + index] = value.toInt().toByte() + } + + public fun fill(value: Double) { + _data.fill(value.toInt().toByte(), _offset, _offset + length.toInt()) + } + + public fun subarray(start: Double, end: Double): Int8Array { + return Int8Array(_data, _offset + start.toInt(), (end - start).toInt()) + } + + public fun set(values: Int8Array, offset: Double) { + values._data.copyInto( + _data, + _offset + offset.toInt(), + values._offset, + values._offset + values.length.toInt() + ) + } + + override fun iterator(): Iterator { + return object : Iterator { + private var _index = 0 + override fun hasNext(): Boolean = _index < length.toInt() + override fun next(): Byte = _data[_offset + _index++] + } + } +} diff --git a/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Uint16Array.kt b/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Uint16Array.kt index a9d4d222e3..62ce6b2ac4 100644 --- a/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Uint16Array.kt +++ b/packages/kotlin/src/android/src/main/java/alphaTab/core/ecmaScript/Uint16Array.kt @@ -4,33 +4,69 @@ package alphaTab.core.ecmaScript @ExperimentalUnsignedTypes internal class Uint16Array : Iterable { private val _data: UShortArray - + private val _offset: Int public val length: Double - get() { - return _data.size.toDouble() - } public constructor(size: Double) { _data = UShortArray(size.toInt()) + _offset = 0 + length = size + } + + public constructor(values: Iterable) { + val list = values.toList() + _data = UShortArray(list.size) + for (i in list.indices) { + _data[i] = list[i].toInt().toUShort() + } + _offset = 0 + length = list.size.toDouble() + } + + private constructor(data: UShortArray, offset: Int, length: Int) { + _data = data + _offset = offset + this.length = length.toDouble() } public inline operator fun get(index: Double): Double { - return _data[index.toInt()].toDouble() + return get(index.toInt()) } public inline operator fun set(index: Double, value: Double) { - _data[index.toInt()] = value.toInt().toUShort() + set(index.toInt(), value) } public inline operator fun get(index: Int): Double { - return _data[index].toDouble() + return _data[_offset + index].toDouble() } public inline operator fun set(index: Int, value: Double) { - _data[index] = value.toUInt().toUShort() + _data[_offset + index] = value.toInt().toUShort() + } + + public fun fill(value: Double) { + _data.fill(value.toInt().toUShort(), _offset, _offset + length.toInt()) + } + + public fun subarray(start: Double, end: Double): Uint16Array { + return Uint16Array(_data, _offset + start.toInt(), (end - start).toInt()) + } + + public fun set(values: Uint16Array, offset: Double) { + values._data.copyInto( + _data, + _offset + offset.toInt(), + values._offset, + values._offset + values.length.toInt() + ) } override fun iterator(): Iterator { - return _data.iterator() + return object : Iterator { + private var _index = 0 + override fun hasNext(): Boolean = _index < length.toInt() + override fun next(): UShort = _data[_offset + _index++] + } } } diff --git a/packages/transpiler/src/TypeResolver.ts b/packages/transpiler/src/TypeResolver.ts index 8b052866d4..19ec468129 100644 --- a/packages/transpiler/src/TypeResolver.ts +++ b/packages/transpiler/src/TypeResolver.ts @@ -125,6 +125,7 @@ export default class TypeResolver { * ArrayBuffer generic. */ private static readonly _typedArraySymbolNames: ReadonlySet = new Set([ + 'Int8Array', 'Uint8Array', 'Int16Array', 'Uint16Array', @@ -692,14 +693,6 @@ export default class TypeResolver { typeArguments: typeArguments } as cs.TypeReference; - if (symbolName === 'Int8Array' && this.isNodeEmitted(node)) { - this._ctx.addNodeDiagnostics( - node, - 'Int8Array is not supported. The C# runtime has no Int8Array class. Use Uint8Array or a custom sbyte[] wrapper instead.', - ts.DiagnosticCategory.Error - ); - } - // Typed arrays (Int8Array, ..., DataView) wrap an ArrayBuffer that // does not exist as a generic on the target type. if (TypeResolver._typedArraySymbolNames.has(symbolName)) { diff --git a/packages/transpiler/test/fixtures/errors/int8array/errors.txt b/packages/transpiler/test/fixtures/errors/int8array/errors.txt deleted file mode 100644 index f53bca98c6..0000000000 --- a/packages/transpiler/test/fixtures/errors/int8array/errors.txt +++ /dev/null @@ -1,2 +0,0 @@ -input.ts:5:20: Int8Array is not supported. The C# runtime has no Int8Array class. Use Uint8Array or a custom sbyte[] wrapper instead. -input.ts:5:36: Int8Array is not supported. The C# runtime has no Int8Array class. Use Uint8Array or a custom sbyte[] wrapper instead. diff --git a/packages/transpiler/test/fixtures/errors/int8array/input.ts b/packages/transpiler/test/fixtures/errors/int8array/input.ts deleted file mode 100644 index 20f52085de..0000000000 --- a/packages/transpiler/test/fixtures/errors/int8array/input.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @public - */ -export class Int8ArrayUsage { - public signed: Int8Array = new Int8Array(0); -} diff --git a/packages/transpiler/test/fixtures/types/typed-arrays/expected.cs b/packages/transpiler/test/fixtures/types/typed-arrays/expected.cs index 91694154a8..fbb15c5664 100644 --- a/packages/transpiler/test/fixtures/types/typed-arrays/expected.cs +++ b/packages/transpiler/test/fixtures/types/typed-arrays/expected.cs @@ -26,6 +26,27 @@ public AlphaTab.Core.EcmaScript.Float32Array Floats } = new AlphaTab.Core.EcmaScript.Float32Array(0); + public AlphaTab.Core.EcmaScript.Int8Array SignedBytes + { + get; + set; + } + = new AlphaTab.Core.EcmaScript.Int8Array(0); + + public AlphaTab.Core.EcmaScript.Int16Array Shorts + { + get; + set; + } + = new AlphaTab.Core.EcmaScript.Int16Array(0); + + public AlphaTab.Core.EcmaScript.Uint16Array UnsignedShorts + { + get; + set; + } + = new AlphaTab.Core.EcmaScript.Uint16Array(0); + public double ByteAt(double i) { return this.Bytes[(int)(i)]; @@ -38,6 +59,18 @@ public AlphaTab.Core.EcmaScript.Uint8Array MakeBuffer(double size) } + public void ResetSigned(double size) + { + this.SignedBytes = new AlphaTab.Core.EcmaScript.Int8Array(size); + this.SignedBytes.Fill(-1); + this.SignedBytes[(int)(0)] = -128; + this.Shorts = new AlphaTab.Core.EcmaScript.Int16Array(size); + this.Shorts.Fill(-1); + this.Shorts.Set(this.Shorts.Subarray(0, 1), 1); + this.UnsignedShorts.Fill(0); + } + + } } diff --git a/packages/transpiler/test/fixtures/types/typed-arrays/expected.kt b/packages/transpiler/test/fixtures/types/typed-arrays/expected.kt index fa93ba69d8..d3c324f322 100644 --- a/packages/transpiler/test/fixtures/types/typed-arrays/expected.kt +++ b/packages/transpiler/test/fixtures/types/typed-arrays/expected.kt @@ -48,6 +48,15 @@ public class TypedArrays public var floats: alphaTab.core.ecmaScript.Float32Array = alphaTab.core.ecmaScript.Float32Array(0.0) + public var signedBytes: alphaTab.core.ecmaScript.Int8Array = alphaTab.core.ecmaScript.Int8Array(0.0) + + + public var shorts: alphaTab.core.ecmaScript.Int16Array = alphaTab.core.ecmaScript.Int16Array(0.0) + + + public var unsignedShorts: alphaTab.core.ecmaScript.Uint16Array = alphaTab.core.ecmaScript.Uint16Array(0.0) + + /** */ public fun byteAt(i: Double): Double{ @@ -60,6 +69,18 @@ public class TypedArrays return alphaTab.core.ecmaScript.Uint8Array(size) } + /** + */ + public fun resetSigned(size: Double): Unit{ + this.signedBytes = alphaTab.core.ecmaScript.Int8Array(size) + this.signedBytes.fill(-1.0) + this.signedBytes[(0).toInt()] = -128.0 + this.shorts = alphaTab.core.ecmaScript.Int16Array(size) + this.shorts.fill(-1.0) + this.shorts.set(this.shorts.subarray(0.0, 1.0), 1.0) + this.unsignedShorts.fill(0.0) + } + public constructor() } diff --git a/packages/transpiler/test/fixtures/types/typed-arrays/input.ts b/packages/transpiler/test/fixtures/types/typed-arrays/input.ts index 276416ee98..e6b89f38d2 100644 --- a/packages/transpiler/test/fixtures/types/typed-arrays/input.ts +++ b/packages/transpiler/test/fixtures/types/typed-arrays/input.ts @@ -4,6 +4,9 @@ export class TypedArrays { public bytes: Uint8Array = new Uint8Array(0); public floats: Float32Array = new Float32Array(0); + public signedBytes: Int8Array = new Int8Array(0); + public shorts: Int16Array = new Int16Array(0); + public unsignedShorts: Uint16Array = new Uint16Array(0); public byteAt(i: number): number { return this.bytes[i]; @@ -12,4 +15,14 @@ export class TypedArrays { public makeBuffer(size: number): Uint8Array { return new Uint8Array(size); } + + public resetSigned(size: number): void { + this.signedBytes = new Int8Array(size); + this.signedBytes.fill(-1); + this.signedBytes[0] = -128; + this.shorts = new Int16Array(size); + this.shorts.fill(-1); + this.shorts.set(this.shorts.subarray(0, 1), 1); + this.unsignedShorts.fill(0); + } } From 5d11f8c17f66f257f03401133413b1eb074d278d Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:18:15 +0100 Subject: [PATCH 02/12] fix(platform): close transpiler and Kotlin runtime gaps for typed numeric code - Compound bitwise assignments (a |= b) now cast the right operand to int like plain bitwise operators do; before, a double right operand did not compile in C# or Kotlin. - A non-null assertion on pop()/shift() of a number/boolean array no longer emits .Value in C#; the runtime helpers return the plain element type. - Kotlin DoubleList.splice(start, deleteCount) copied the wrong range and corrupted or threw for removals before the end; it now matches JS and clamps like JS. Adds the inserting splice(start, deleteCount, ...items). - Kotlin BooleanList.fill and List.fill return the list like JS fill. --- .../java/alphaTab/collections/BooleanList.kt | 3 +- .../java/alphaTab/collections/DoubleList.kt | 34 +++++++++++++------ .../main/java/alphaTab/collections/List.kt | 3 +- .../transpiler/src/transforms/Operators.ts | 31 +++++++++++++++-- .../fixtures/expressions/binary/expected.cs | 2 +- .../fixtures/expressions/binary/expected.kt | 2 +- 6 files changed, 57 insertions(+), 18 deletions(-) diff --git a/packages/kotlin/src/android/src/main/java/alphaTab/collections/BooleanList.kt b/packages/kotlin/src/android/src/main/java/alphaTab/collections/BooleanList.kt index b221abfd3c..8e0870ee07 100644 --- a/packages/kotlin/src/android/src/main/java/alphaTab/collections/BooleanList.kt +++ b/packages/kotlin/src/android/src/main/java/alphaTab/collections/BooleanList.kt @@ -48,8 +48,9 @@ internal class BooleanList : IBooleanIterable { return Iterator(this) } - public fun fill(b: Boolean) { + public fun fill(b: Boolean): BooleanList { _data.fill(b, 0, _size) + return this } public fun spread(): BooleanArray { diff --git a/packages/kotlin/src/android/src/main/java/alphaTab/collections/DoubleList.kt b/packages/kotlin/src/android/src/main/java/alphaTab/collections/DoubleList.kt index 5710787452..de9097912c 100644 --- a/packages/kotlin/src/android/src/main/java/alphaTab/collections/DoubleList.kt +++ b/packages/kotlin/src/android/src/main/java/alphaTab/collections/DoubleList.kt @@ -176,17 +176,29 @@ public class DoubleList : IDoubleIterable { } public fun splice(start: Double, deleteCount: Double) { - val firstAfterDelete = (start + deleteCount).toInt() - val itemsAfterDelete = this.length.toInt() - firstAfterDelete; - if(itemsAfterDelete > 0) { - _items.copyInto( - _items, - start.toInt(), - firstAfterDelete, - itemsAfterDelete - ) - } - this._size -= deleteCount.toInt() + val startIndex = start.toInt().coerceIn(0, _size) + val removed = deleteCount.toInt().coerceIn(0, _size - startIndex) + val firstAfterDelete = startIndex + removed + if (firstAfterDelete < _size) { + _items.copyInto(_items, startIndex, firstAfterDelete, _size) + } + this._size -= removed + } + + public fun splice(start: Double, deleteCount: Double, vararg newElements: Double) { + splice(start, deleteCount) + val insertAt = start.toInt().coerceIn(0, _size) + val inserted = newElements.size + if (inserted == 0) { + return + } + val size = _size + if (size + inserted > _items.size) { + grow(size + inserted) + } + _items.copyInto(_items, insertAt + inserted, insertAt, size) + newElements.copyInto(_items, insertAt) + _size = size + inserted } private class Iterator(private val list: DoubleList) : DoubleIterator() { private var _index = 0 diff --git a/packages/kotlin/src/android/src/main/java/alphaTab/collections/List.kt b/packages/kotlin/src/android/src/main/java/alphaTab/collections/List.kt index aa9b453eb0..79be8f90cd 100644 --- a/packages/kotlin/src/android/src/main/java/alphaTab/collections/List.kt +++ b/packages/kotlin/src/android/src/main/java/alphaTab/collections/List.kt @@ -57,8 +57,9 @@ public class List : Iterable { _data.add(item) } - public fun fill(item: T) { + public fun fill(item: T): List { _data.fill(item) + return this } public fun push(vararg items: T) { diff --git a/packages/transpiler/src/transforms/Operators.ts b/packages/transpiler/src/transforms/Operators.ts index 2c0f549e6f..bd429e7c79 100644 --- a/packages/transpiler/src/transforms/Operators.ts +++ b/packages/transpiler/src/transforms/Operators.ts @@ -147,11 +147,17 @@ function _visitBitwiseAssignmentBinaryOp(state: AstTransformer, parent: cs.Node, return null; } - (bitOp.right as cs.ParenthesizedExpression).expression = state.visitExpression(bitOp.right, expression.right)!; - - if (!(bitOp.right as cs.ParenthesizedExpression).expression) { + const right = state.visitExpression(bitOp.right, expression.right)!; + if (!right) { return null; } + const isShift = + expression.operatorToken.kind === ts.SyntaxKind.LessThanLessThanEqualsToken || + expression.operatorToken.kind === ts.SyntaxKind.GreaterThanGreaterThanEqualsToken || + expression.operatorToken.kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken; + (bitOp.right as cs.ParenthesizedExpression).expression = _hasBinaryOperationMakeInt(state, right) + ? right + : makeInt(state, right, !isShift); } else { (bitOp.left as cs.ParenthesizedExpression).expression = state.visitExpression(assignment, expression.left)!; @@ -493,7 +499,26 @@ export function visitAsExpression( return castExpression; } +/** + * Whether the expression reads an element of a value-type array through a runtime helper + * which returns the plain element type (e.g. `IList.Pop()`), not a nullable one. + */ +function _isArrayElementRemoval(state: AstTransformer, expression: ts.Expression): boolean { + if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) { + return false; + } + const name = expression.expression.name.text; + if (name !== 'pop' && name !== 'shift') { + return false; + } + const receiverType = state.context.typeChecker.getTypeAtLocation(expression.expression.expression); + return state.context.typeChecker.isArrayType(receiverType); +} + export function visitNonNullExpression(state: AstTransformer, parent: cs.Node, expression: ts.NonNullExpression) { + if (state.context.isValueTypeExpression(expression) && _isArrayElementRemoval(state, expression.expression)) { + return state.visitExpression(parent, expression.expression); + } if (state.context.isValueTypeExpression(expression)) { const valueAccessExpression = { expression: {} as cs.Expression, diff --git a/packages/transpiler/test/fixtures/expressions/binary/expected.cs b/packages/transpiler/test/fixtures/expressions/binary/expected.cs index 0bd33d0ba0..241d613348 100644 --- a/packages/transpiler/test/fixtures/expressions/binary/expected.cs +++ b/packages/transpiler/test/fixtures/expressions/binary/expected.cs @@ -44,7 +44,7 @@ public double UnsignedShift(double a) public double Mask(double a, double m) { double x = a; - x = (double)(((int)x) & (m)); + x = (double)(((int)x) & ((int)(m))); x = (double)(((int)x) | (16)); x = (double)(((int)x) ^ (255)); x = (double)(((int)x) << (2)); diff --git a/packages/transpiler/test/fixtures/expressions/binary/expected.kt b/packages/transpiler/test/fixtures/expressions/binary/expected.kt index 851327ba43..c49cb88941 100644 --- a/packages/transpiler/test/fixtures/expressions/binary/expected.kt +++ b/packages/transpiler/test/fixtures/expressions/binary/expected.kt @@ -75,7 +75,7 @@ public class Binary */ public fun mask(a: Double, m: Double): Double{ var x: Double = a - x = ((x.toInt()) and (m)).toDouble() + x = ((x.toInt()) and ((m).toInt())).toDouble() x = ((x.toInt()) or (16)).toDouble() x = ((x.toInt()) xor (255)).toDouble() x = ((x.toInt()) shl (2)).toDouble() From 6f20eb84c6453d09e969756c999159050bc2bce4 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:18:15 +0100 Subject: [PATCH 03/12] feat(rendering): add display-time tab fingering solver for transposed staves TabFingeringSolver decides on which string and fret tab notes are shown when the staff is transposed, purely from the model. Notes keep their string whenever the transposed fret is playable; otherwise the bars connected by ties, slides and hammer-ons/pull-offs are re-fingered with a beam search preferring fewer unplayable notes, fewer moved notes and less hand movement and stretch. Natural harmonics are mapped to the node of the transposed pitch, or shown as artificial harmonic when none exists. Not yet wired into rendering. --- .../rendering/utils/TabFingeringSegment.ts | 90 ++ .../src/rendering/utils/TabFingeringSolver.ts | 1082 +++++++++++++++++ .../test/rendering/TabFingeringSolver.test.ts | 197 +++ 3 files changed, 1369 insertions(+) create mode 100644 packages/alphatab/src/rendering/utils/TabFingeringSegment.ts create mode 100644 packages/alphatab/src/rendering/utils/TabFingeringSolver.ts create mode 100644 packages/alphatab/test/rendering/TabFingeringSolver.test.ts diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSegment.ts b/packages/alphatab/src/rendering/utils/TabFingeringSegment.ts new file mode 100644 index 0000000000..5e2ef85e7a --- /dev/null +++ b/packages/alphatab/src/rendering/utils/TabFingeringSegment.ts @@ -0,0 +1,90 @@ +import type { Note } from '@coderline/alphatab/model/Note'; + +/** + * The display fingering (string, fret, harmonic node) of all notes of a run of bars of one staff, + * as decided by {@link TabFingeringSolver}. Values are only meaningful for stringed notes of the bars + * from {@link firstBarIndex} to {@link lastBarIndex}. + * @internal + */ +export class TabFingeringSegment { + /** + * The note is displayed on another string than in the model. + */ + public static readonly flagMoved: number = 1; + /** + * No position on the tuning can play the note, it keeps its model string with an out of range fret. + */ + public static readonly flagUnplayable: number = 2; + /** + * A natural harmonic without a matching node, displayed as artificial harmonic an octave above the fret. + */ + public static readonly flagAsArtificial: number = 4; + + public readonly firstBarIndex: number; + public readonly lastBarIndex: number; + + private readonly _barVoiceBase: Int32Array; + private readonly _voiceBeatBase: Int32Array; + private readonly _beatNoteBase: Int32Array; + private readonly _strings: Uint8Array; + private readonly _frets: Int16Array; + private readonly _nodes: Int8Array; + private readonly _flags: Uint8Array; + + public constructor( + firstBarIndex: number, + lastBarIndex: number, + barVoiceBase: Int32Array, + voiceBeatBase: Int32Array, + beatNoteBase: Int32Array, + noteCount: number + ) { + this.firstBarIndex = firstBarIndex; + this.lastBarIndex = lastBarIndex; + this._barVoiceBase = barVoiceBase; + this._voiceBeatBase = voiceBeatBase; + this._beatNoteBase = beatNoteBase; + this._strings = new Uint8Array(noteCount); + this._frets = new Int16Array(noteCount); + this._nodes = new Int8Array(noteCount); + this._nodes.fill(-1); + this._flags = new Uint8Array(noteCount); + } + + public covers(barIndex: number): boolean { + return barIndex >= this.firstBarIndex && barIndex <= this.lastBarIndex; + } + + public noteIndex(note: Note): number { + const beat = note.beat; + const voice = beat.voice; + const voiceIndex = this._barVoiceBase[voice.bar.index - this.firstBarIndex] + voice.index; + return this._beatNoteBase[this._voiceBeatBase[voiceIndex] + beat.index] + note.index; + } + + public getString(note: Note): number { + return this._strings[this.noteIndex(note)]; + } + + public getFret(note: Note): number { + return this._frets[this.noteIndex(note)]; + } + + /** + * The index into {@link TabFingeringSolver.naturalNodeValues} for natural harmonics, -1 otherwise. + */ + public getNode(note: Note): number { + return this._nodes[this.noteIndex(note)]; + } + + public getFlags(note: Note): number { + return this._flags[this.noteIndex(note)]; + } + + public set(index: number, str: number, fret: number, node: number, flags: number): void { + this._strings[index] = str; + this._frets[index] = fret; + this._nodes[index] = node; + this._flags[index] = flags; + } +} diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts new file mode 100644 index 0000000000..353f100f13 --- /dev/null +++ b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts @@ -0,0 +1,1082 @@ +import type { Beat } from '@coderline/alphatab/model/Beat'; +import { GraceType } from '@coderline/alphatab/model/GraceType'; +import { HarmonicType } from '@coderline/alphatab/model/HarmonicType'; +import { ModelUtils } from '@coderline/alphatab/model/ModelUtils'; +import type { Note } from '@coderline/alphatab/model/Note'; +import { SlideInType } from '@coderline/alphatab/model/SlideInType'; +import { SlideOutType } from '@coderline/alphatab/model/SlideOutType'; +import type { Staff } from '@coderline/alphatab/model/Staff'; +import { VibratoType } from '@coderline/alphatab/model/VibratoType'; +import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; + +/** + * Cost weights for {@link TabFingeringSolver}. Position weights follow {@link FingeringOptions}. + * @internal + */ +export class TabFingeringOptions { + /** + * The highest fret counted from the nut; notes using a higher fret in the model raise the limit for themselves. + */ + public defaultMaxFret: number = 24; + public maxSpan: number = 5; + public spanWeight: number = 0.25; + /** Per fret of span beyond {@link maxSpan}. */ + public overSpanPenalty: number = 10; + public highFretThreshold: number = 12; + public highFretPenaltyWeight: number = 0.5; + /** Negative = prefer open strings. */ + public openStringBonus: number = -1; + /** Cost of placing a note on a string which is still sounding from an earlier beat. */ + public occupancyPenalty: number = 8; + public asArtificialPenalty: number = 20; + public handMovementWeight: number = 1; + public beamWidth: number = 16; + public maxLeavesPerState: number = 256; +} + +/** + * Decides on which string and fret tab notes are displayed when the staff is transposed. + * Works purely on the model and never modifies it. + * + * Notes keep their model string whenever the transposed fret is playable there. Otherwise the + * bars connected by ties, slides and hammer-ons/pull-offs are re-fingered together, preferring + * (in this order) fewer unplayable notes, fewer notes moved to another string and a smaller + * hand movement and stretch. + * @internal + */ +export class TabFingeringSolver { + /** + * The harmonic values of the natural harmonic nodes, as produced by + * {@link ModelUtils.deltaFretToHarmonicValue} plus the extra nodes known by {@link ModelUtils.harmonicValueToPitch}. + */ + public static readonly naturalNodeValues: number[] = [ + 12, 7, 19, 5, 24, 4, 9, 16, 3.2, 2.7, 5.8, 9.6, 14.7, 2.4, 8.2, 17, 21.7 + ]; + + // the semitones above the open string for each entry of naturalNodeValues + private static readonly _naturalNodeIntervals: number[] = [ + 12, 19, 19, 24, 24, 28, 28, 28, 31, 34, 34, 34, 34, 36, 36, 36, 36 + ]; + + // Note.nextNoteOnSameLine and findHammerPullDestination search up to 3 bars ahead + private static readonly _maxLinkBarDistance: number = 4; + + private static readonly _defaultOptions: TabFingeringOptions = new TabFingeringOptions(); + + /** + * Whether the tab of the given staff is displayed with a fingering differing from the model. + */ + public static isActive(staff: Staff): boolean { + return staff.transpositionPitch !== 0 && !staff.isPercussion && staff.tuning.length > 0; + } + + public static isNaturalHarmonic(note: Note): boolean { + return note.harmonicType === HarmonicType.Natural && !ModelUtils.isAlmostEqualTo(note.harmonicValue, 0); + } + + /** + * Finds the natural harmonic node sounding the given interval above the open string. + * @param interval The semitones above the open string. + * @param preferredValue The harmonic value to stay closest to. + * @returns The index into {@link naturalNodeValues} or -1 if no node sounds this interval. + */ + public static findNaturalNode(interval: number, preferredValue: number): number { + let best = -1; + let bestDistance = 0; + const intervals = TabFingeringSolver._naturalNodeIntervals; + const values = TabFingeringSolver.naturalNodeValues; + for (let i = 0; i < intervals.length; i++) { + if (intervals[i] === interval) { + const distance = Math.abs(values[i] - preferredValue); + if (best === -1 || distance < bestDistance) { + best = i; + bestDistance = distance; + } + } + } + return best; + } + + /** + * The node of a natural harmonic which stays on its model string. + */ + public static findNaturalNodeOnModelString(note: Note): number { + const staff = note.beat.voice.bar.staff; + return TabFingeringSolver.findNaturalNode( + ModelUtils.harmonicValueToPitch(note.harmonicValue) - staff.transpositionPitch, + note.harmonicValue + ); + } + + /** + * Whether no note before the given bar is linked to a note in or after it. + */ + public static isSegmentStart(staff: Staff, barIndex: number): boolean { + const firstChecked = Math.max(0, barIndex - TabFingeringSolver._maxLinkBarDistance); + for (let b = barIndex - 1; b >= firstChecked; b--) { + for (const voice of staff.bars[b].voices) { + for (const beat of voice.beats) { + for (const note of beat.notes) { + for (let kind = 0; kind < 3; kind++) { + const target = TabFingeringSolver.nextLinked(note, kind); + if (target !== null && target.beat.voice.bar.index >= barIndex) { + return false; + } + } + } + } + } + } + return true; + } + + /** + * The first bar of the segment containing the given bar. + */ + public static segmentStart(staff: Staff, barIndex: number): number { + let b = barIndex; + while (b > 0 && !TabFingeringSolver.isSegmentStart(staff, b)) { + b--; + } + return b; + } + + /** + * The last bar of the segment starting at the given bar. + */ + public static segmentEnd(staff: Staff, firstBarIndex: number): number { + let last = firstBarIndex; + let scanned = firstBarIndex; + while (scanned <= last && scanned < staff.bars.length) { + for (const voice of staff.bars[scanned].voices) { + for (const beat of voice.beats) { + for (const note of beat.notes) { + for (let kind = 0; kind < 3; kind++) { + const target = TabFingeringSolver.nextLinked(note, kind); + if (target !== null && target.beat.voice.bar.index > last) { + last = target.beat.voice.bar.index; + } + } + } + } + } + scanned++; + } + return last; + } + + /** + * Solves the display fingering of the given bars, which must form a segment. + * @returns The fingering or null if all notes keep their model string and fret shifted by the transposition. + */ + public static solve( + staff: Staff, + firstBarIndex: number, + lastBarIndex: number, + options?: TabFingeringOptions + ): TabFingeringSegment | null { + const run = new TabFingeringRun( + staff, + firstBarIndex, + lastBarIndex, + options ?? TabFingeringSolver._defaultOptions + ); + return run.solve(); + } + + /** + * The note which has to stay on the same string as the given one: 0 = tie, 1 = slide, 2 = hammer-on/pull-off. + */ + public static nextLinked(note: Note, kind: number): Note | null { + switch (kind) { + case 0: + return note.tieDestination; + case 1: + return note.slideOutType === SlideOutType.Shift || note.slideOutType === SlideOutType.Legato + ? note.slideTarget + : null; + case 2: + return note.isHammerPullOrigin ? note.hammerPullDestination : null; + } + return null; + } + + public static previousLinked(note: Note, kind: number): Note | null { + switch (kind) { + case 0: + return note.isTieDestination ? note.tieOrigin : null; + case 1: + return note.slideOrigin; + case 2: + return note.hammerPullOrigin; + } + return null; + } +} + +/** + * The state of one {@link TabFingeringSolver.solve} call. + * + * Notes linked by ties, slides and hammer-ons/pull-offs form a group which moves as a whole by a + * string delta, keeping the string offsets of the model. The beats of all voices are merged into + * time slices and a beam search over the slices picks one delta per group. + * @internal + */ +export class TabFingeringRun { + private static readonly _kindSkip: number = 0; + private static readonly _kindNormal: number = 1; + private static readonly _kindDead: number = 2; + private static readonly _kindNatural: number = 3; + + private static readonly _graceRankMain: number = 1000; + private static readonly _ticksPerQuarter: number = 960; + + private readonly _staff: Staff; + private readonly _firstBarIndex: number; + private readonly _lastBarIndex: number; + private readonly _options: TabFingeringOptions; + private readonly _capo: number; + private readonly _tuning: number[]; + private readonly _stringCount: number; + + private _barVoiceBase!: Int32Array; + private _voiceBeatBase!: Int32Array; + private _beatNoteBase!: Int32Array; + private _notes: Note[] = []; + + private _kind!: Uint8Array; + private _target!: Int32Array; + private _originalString!: Int32Array; + private _maxFret!: Int32Array; + private _noOpen!: Uint8Array; + private _trill!: Int32Array; + private _group!: Int32Array; + private _slice!: Int32Array; + private _sustainEnd!: Int32Array; + + private _groupCount: number = 0; + private _groupFirst: number[] = []; + private _groupLast: number[] = []; + private _groupOptionBase: number[] = []; + private _groupOptions: number[] = []; + + private _sliceTick: number[] = []; + private _sliceNoteBase: number[] = []; + private _sliceNotes: number[] = []; + private _soundBase: number[] = []; + private _soundNotes: number[] = []; + private _activeBase: number[] = []; + private _activeGroups: number[] = []; + + // results of _evaluate + private _evalFret: number = 0; + private _evalNode: number = -1; + private _evalFlags: number = 0; + + public constructor(staff: Staff, firstBarIndex: number, lastBarIndex: number, options: TabFingeringOptions) { + this._staff = staff; + this._firstBarIndex = firstBarIndex; + this._lastBarIndex = lastBarIndex; + this._options = options; + this._capo = staff.capo; + this._tuning = staff.tuning; + this._stringCount = staff.tuning.length; + } + + public solve(): TabFingeringSegment | null { + this._collectNotes(); + if (this._isIdentity()) { + return null; + } + + this._buildGroups(); + this._buildSlices(); + this._buildGroupSpans(); + const groupDelta = this._search(); + + const segment = new TabFingeringSegment( + this._firstBarIndex, + this._lastBarIndex, + this._barVoiceBase, + this._voiceBeatBase, + this._beatNoteBase, + this._notes.length + ); + for (let i = 0; i < this._notes.length; i++) { + if (this._kind[i] === TabFingeringRun._kindSkip) { + continue; + } + const delta = groupDelta[this._group[i]]; + const str = this._originalString[i] + delta; + const valid = this._evaluate(i, str); + let flags = this._evalFlags; + if (delta !== 0) { + flags |= TabFingeringSegment.flagMoved; + } + if (!valid) { + flags |= TabFingeringSegment.flagUnplayable; + } + segment.set(i, str, this._evalFret, this._evalNode, flags); + } + return segment; + } + + private _collectNotes(): void { + const bars = this._staff.bars; + let voiceCount = 0; + let beatCount = 0; + for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { + for (const voice of bars[b].voices) { + voiceCount++; + beatCount += voice.beats.length; + } + } + + this._barVoiceBase = new Int32Array(this._lastBarIndex - this._firstBarIndex + 1); + this._voiceBeatBase = new Int32Array(voiceCount); + this._beatNoteBase = new Int32Array(beatCount); + + const notes = this._notes; + let voiceIndex = 0; + let beatIndex = 0; + for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { + this._barVoiceBase[b - this._firstBarIndex] = voiceIndex; + for (const voice of bars[b].voices) { + this._voiceBeatBase[voiceIndex] = beatIndex; + voiceIndex++; + for (const beat of voice.beats) { + this._beatNoteBase[beatIndex] = notes.length; + beatIndex++; + for (const note of beat.notes) { + notes.push(note); + } + } + } + } + + const count = notes.length; + this._kind = new Uint8Array(count); + this._target = new Int32Array(count); + this._originalString = new Int32Array(count); + this._maxFret = new Int32Array(count); + this._noOpen = new Uint8Array(count); + this._trill = new Int32Array(count); + this._group = new Int32Array(count); + this._slice = new Int32Array(count); + this._sustainEnd = new Int32Array(count); + + const transpositionPitch = this._staff.transpositionPitch; + for (let i = 0; i < count; i++) { + const note = notes[i]; + this._group[i] = -1; + this._slice[i] = -1; + if (!note.isStringed || note.string < 1 || note.string > this._stringCount) { + this._kind[i] = TabFingeringRun._kindSkip; + continue; + } + + if (note.isDead) { + this._kind[i] = TabFingeringRun._kindDead; + this._target[i] = note.realValueWithoutHarmonic; + } else if (TabFingeringSolver.isNaturalHarmonic(note)) { + this._kind[i] = TabFingeringRun._kindNatural; + this._target[i] = note.realValue; + } else { + this._kind[i] = TabFingeringRun._kindNormal; + this._target[i] = note.realValueWithoutHarmonic; + } + this._originalString[i] = note.string; + this._maxFret[i] = Math.max(this._options.defaultMaxFret - this._capo, note.fret); + this._noOpen[i] = TabFingeringRun._needsFrettedString(note) ? 1 : 0; + this._trill[i] = note.isTrill ? note.trillValue - transpositionPitch : -1; + } + } + + private static _needsFrettedString(note: Note): boolean { + if (note.hasBend || note.isContinuedBend || note.vibrato !== VibratoType.None || note.isLeftHandTapped) { + return true; + } + if (note.slideInType === SlideInType.IntoFromBelow || note.slideInType === SlideInType.IntoFromAbove) { + return true; + } + switch (note.slideOutType) { + case SlideOutType.Shift: + case SlideOutType.Legato: + case SlideOutType.OutUp: + case SlideOutType.OutDown: + return true; + } + if (note.slideOrigin !== null) { + return true; + } + // a hammer-on cannot end on an open string, a pull-off can + const hammerPullOrigin = note.hammerPullOrigin; + if (hammerPullOrigin !== null && hammerPullOrigin.realValue < note.realValue) { + return true; + } + return false; + } + + private _stringPitch(str: number): number { + return this._capo + this._tuning[this._stringCount - str]; + } + + /** + * Evaluates the note on the given string into {@link _evalFret}, {@link _evalNode} and {@link _evalFlags}. + * @returns Whether the note can be played there. + */ + private _evaluate(i: number, str: number): boolean { + const stringPitch = this._stringPitch(str); + const target = this._target[i]; + const maxFret = this._maxFret[i]; + this._evalNode = -1; + this._evalFlags = 0; + switch (this._kind[i]) { + case TabFingeringRun._kindDead: + this._evalFret = target - stringPitch; + return true; + case TabFingeringRun._kindNatural: { + const node = TabFingeringSolver.findNaturalNode(target - stringPitch, this._notes[i].harmonicValue); + if (node >= 0) { + this._evalFret = 0; + this._evalNode = node; + return true; + } + const baseFret = target - 12 - stringPitch; + this._evalFret = baseFret; + this._evalFlags = TabFingeringSegment.flagAsArtificial; + return baseFret >= 0 && baseFret <= maxFret; + } + } + + const fret = target - stringPitch; + this._evalFret = fret; + if (fret < 0 || fret > maxFret) { + return false; + } + if (fret === 0 && this._noOpen[i] !== 0) { + return false; + } + const trill = this._trill[i]; + if (trill >= 0) { + const trillFret = trill - stringPitch; + if (trillFret < 0 || trillFret > maxFret) { + return false; + } + } + return true; + } + + private _isIdentity(): boolean { + for (let i = 0; i < this._notes.length; i++) { + if (this._kind[i] !== TabFingeringRun._kindSkip && !this._evaluate(i, this._originalString[i])) { + return false; + } + } + return true; + } + + private _indexOf(note: Note): number { + const bar = note.beat.voice.bar; + if (bar.staff !== this._staff || bar.index < this._firstBarIndex || bar.index > this._lastBarIndex) { + return -1; + } + const voiceIndex = this._barVoiceBase[bar.index - this._firstBarIndex] + note.beat.voice.index; + return this._beatNoteBase[this._voiceBeatBase[voiceIndex] + note.beat.index] + note.index; + } + + private _buildGroups(): void { + const count = this._notes.length; + const stack: number[] = []; + const groupMembers: number[] = []; + const groupMemberBase: number[] = []; + for (let i = 0; i < count; i++) { + if (this._kind[i] === TabFingeringRun._kindSkip || this._group[i] >= 0) { + continue; + } + const g = this._groupCount; + this._groupCount++; + groupMemberBase.push(groupMembers.length); + this._group[i] = g; + stack.push(i); + while (stack.length > 0) { + const current = stack.pop()!; + groupMembers.push(current); + const note = this._notes[current]; + for (let kind = 0; kind < 3; kind++) { + for (let direction = 0; direction < 2; direction++) { + const linked = + direction === 0 + ? TabFingeringSolver.nextLinked(note, kind) + : TabFingeringSolver.previousLinked(note, kind); + if (linked === null) { + continue; + } + const linkedIndex = this._indexOf(linked); + if ( + linkedIndex >= 0 && + this._kind[linkedIndex] !== TabFingeringRun._kindSkip && + this._group[linkedIndex] < 0 + ) { + this._group[linkedIndex] = g; + stack.push(linkedIndex); + } + } + } + } + } + groupMemberBase.push(groupMembers.length); + + // the string deltas keeping all members on the instrument, playable ones first + const options = this._groupOptions; + const optionFret: number[] = []; + for (let g = 0; g < this._groupCount; g++) { + this._groupOptionBase.push(options.length); + const memberStart = groupMemberBase[g]; + const memberEnd = groupMemberBase[g + 1]; + let minString = this._stringCount; + let maxString = 1; + let head = groupMembers[memberStart]; + for (let m = memberStart; m < memberEnd; m++) { + const member = groupMembers[m]; + minString = Math.min(minString, this._originalString[member]); + maxString = Math.max(maxString, this._originalString[member]); + if (member < head) { + head = member; + } + } + + const optionStart = options.length; + let hasZero = false; + for (let delta = 1 - minString; delta <= this._stringCount - maxString; delta++) { + let valid = true; + for (let m = memberStart; m < memberEnd && valid; m++) { + const member = groupMembers[m]; + valid = this._evaluate(member, this._originalString[member] + delta); + } + if (!valid) { + continue; + } + this._evaluate(head, this._originalString[head] + delta); + const headFret = this._evalFret; + // order: model string, then lower fret, then lower string + let insertAt = options.length; + if (delta === 0) { + insertAt = optionStart; + hasZero = true; + } else { + while (insertAt > optionStart) { + const previousDelta = options[insertAt - 1]; + const previousFret = optionFret[insertAt - 1]; + if (previousDelta === 0 || previousFret < headFret || (previousFret === headFret && previousDelta < delta)) { + break; + } + insertAt--; + } + } + options.splice(insertAt, 0, delta); + optionFret.splice(insertAt, 0, headFret); + } + if (!hasZero) { + // last resort: keep the model strings, unplayable notes are flagged + options.push(0); + optionFret.push(0); + } + } + this._groupOptionBase.push(options.length); + } + + private static _graceRank(beat: Beat): number { + return beat.graceType === GraceType.None ? TabFingeringRun._graceRankMain : beat.graceIndex; + } + + private static _compareBeats(a: Beat, b: Beat): number { + if (a.voice.bar.index !== b.voice.bar.index) { + return a.voice.bar.index - b.voice.bar.index; + } + if (a.displayStart !== b.displayStart) { + return a.displayStart - b.displayStart; + } + const rankA = TabFingeringRun._graceRank(a); + const rankB = TabFingeringRun._graceRank(b); + if (rankA !== rankB) { + return rankA - rankB; + } + if (a.voice.index !== b.voice.index) { + return a.voice.index - b.voice.index; + } + return a.index - b.index; + } + + private _buildSlices(): void { + const bars = this._staff.bars; + const beats: Beat[] = []; + for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { + for (const voice of bars[b].voices) { + for (const beat of voice.beats) { + for (const note of beat.notes) { + const i = this._indexOf(note); + if (this._kind[i] !== TabFingeringRun._kindSkip) { + beats.push(beat); + break; + } + } + } + } + } + beats.sort((a, b) => TabFingeringRun._compareBeats(a, b)); + + const endTick: number[] = []; + const sliceTick = this._sliceTick; + let previous: Beat | null = null; + for (const beat of beats) { + if ( + previous === null || + previous.voice.bar.index !== beat.voice.bar.index || + previous.displayStart !== beat.displayStart || + TabFingeringRun._graceRank(previous) !== TabFingeringRun._graceRank(beat) + ) { + this._sliceNoteBase.push(this._sliceNotes.length); + sliceTick.push(beat.absoluteDisplayStart); + } + previous = beat; + const slice = sliceTick.length - 1; + for (const note of beat.notes) { + const i = this._indexOf(note); + if (this._kind[i] === TabFingeringRun._kindSkip) { + continue; + } + this._slice[i] = slice; + this._sliceNotes.push(i); + let end = beat.absoluteDisplayStart + beat.displayDuration; + const letRingDestination = note.isLetRing ? note.letRingDestination : null; + if (letRingDestination !== null) { + const destinationBeat = letRingDestination.beat; + end = Math.max(end, destinationBeat.absoluteDisplayStart + destinationBeat.displayDuration); + } + endTick.push(end); + } + } + this._sliceNoteBase.push(this._sliceNotes.length); + + // notes still sounding in later slices + const sliceCount = sliceTick.length; + const soundCount: number[] = new Array(sliceCount).fill(0); + for (let k = 0; k < this._sliceNotes.length; k++) { + const i = this._sliceNotes[k]; + let last = this._slice[i]; + while (last + 1 < sliceCount && sliceTick[last + 1] < endTick[k]) { + last++; + soundCount[last]++; + } + this._sustainEnd[i] = last; + } + this._fillBuckets(soundCount, this._soundBase); + const soundFill: number[] = this._soundBase.slice(0, sliceCount); + for (let s = 0; s < this._soundBase[sliceCount]; s++) { + this._soundNotes.push(0); + } + for (let k = 0; k < this._sliceNotes.length; k++) { + const i = this._sliceNotes[k]; + for (let t = this._slice[i] + 1; t <= this._sustainEnd[i]; t++) { + this._soundNotes[soundFill[t]] = i; + soundFill[t]++; + } + } + } + + private _fillBuckets(counts: number[], base: number[]): void { + let sum = 0; + for (const c of counts) { + base.push(sum); + sum += c; + } + base.push(sum); + } + + private _buildGroupSpans(): void { + const groupCount = this._groupCount; + for (let g = 0; g < groupCount; g++) { + this._groupFirst.push(-1); + this._groupLast.push(-1); + } + for (let i = 0; i < this._notes.length; i++) { + const g = this._group[i]; + if (g < 0 || this._slice[i] < 0) { + continue; + } + if (this._groupFirst[g] < 0 || this._slice[i] < this._groupFirst[g]) { + this._groupFirst[g] = this._slice[i]; + } + if (this._sustainEnd[i] > this._groupLast[g]) { + this._groupLast[g] = this._sustainEnd[i]; + } + } + + const sliceCount = this._sliceTick.length; + const activeCount: number[] = new Array(sliceCount).fill(0); + for (let g = 0; g < groupCount; g++) { + for (let t = this._groupFirst[g]; t >= 0 && t <= this._groupLast[g]; t++) { + activeCount[t]++; + } + } + this._fillBuckets(activeCount, this._activeBase); + const activeFill: number[] = this._activeBase.slice(0, sliceCount); + for (let s = 0; s < this._activeBase[sliceCount]; s++) { + this._activeGroups.push(0); + } + for (let g = 0; g < groupCount; g++) { + for (let t = this._groupFirst[g]; t >= 0 && t <= this._groupLast[g]; t++) { + this._activeGroups[activeFill[t]] = g; + activeFill[t]++; + } + } + } + + /** + * Beam search over the slices, each state holding the string delta of every group active in its slice. + * @returns The string delta per group. + */ + private _search(): number[] { + const options = this._options; + const beamWidth = options.beamWidth; + const sliceCount = this._sliceTick.length; + + // committed states of all slices + const stateBase: number[] = []; + const stateCount: number[] = []; + const stUnplayable: number[] = []; + const stMoved: number[] = []; + const stRest: number[] = []; + const stCenter: number[] = []; + const stBack: number[] = []; + const stDeltaBase: number[] = []; + const stDeltas: number[] = []; + + // candidates of the current slice + const cUnplayable: number[] = []; + const cMoved: number[] = []; + const cRest: number[] = []; + const cCenter: number[] = []; + const cBack: number[] = []; + const cSequence: number[] = []; + const cDeltas: number[] = []; + + const groupDelta: number[] = new Array(this._groupCount).fill(0); + const choice: number[] = []; + const newGroups: number[] = []; + + for (let t = 0; t < sliceCount; t++) { + const activeStart = this._activeBase[t]; + const activeEnd = this._activeBase[t + 1]; + const activeLength = activeEnd - activeStart; + newGroups.splice(0, newGroups.length); + for (let a = activeStart; a < activeEnd; a++) { + const g = this._activeGroups[a]; + if (this._groupFirst[g] === t) { + newGroups.push(g); + } + } + + let candidateCount = 0; + let sequence = 0; + const previousStart = t === 0 ? -1 : stateBase[t - 1]; + const previousCount = t === 0 ? 1 : stateCount[t - 1]; + const gapQuarters = t === 0 ? 0 : (this._sliceTick[t] - this._sliceTick[t - 1]) / TabFingeringRun._ticksPerQuarter; + + for (let p = 0; p < previousCount; p++) { + const previousState = previousStart + p; + let previousUnplayable = 0; + let previousMoved = 0; + let previousRest = 0; + let previousCenter = -1; + if (t > 0) { + previousUnplayable = stUnplayable[previousState]; + previousMoved = stMoved[previousState]; + previousRest = stRest[previousState]; + previousCenter = stCenter[previousState]; + // groups continuing from the previous slice keep their delta + const previousActiveStart = this._activeBase[t - 1]; + const previousActiveEnd = this._activeBase[t]; + const deltaBase = stDeltaBase[previousState]; + for (let a = previousActiveStart; a < previousActiveEnd; a++) { + groupDelta[this._activeGroups[a]] = stDeltas[deltaBase + (a - previousActiveStart)]; + } + } + + choice.splice(0, choice.length); + for (let k = 0; k < newGroups.length; k++) { + choice.push(0); + } + + let leaves = 0; + let done = false; + while (!done && leaves < options.maxLeavesPerState) { + for (let k = 0; k < newGroups.length; k++) { + const g = newGroups[k]; + groupDelta[g] = this._groupOptions[this._groupOptionBase[g] + choice[k]]; + } + leaves++; + + this._scoreSlice(t, groupDelta, previousCenter, gapQuarters); + const unplayable = previousUnplayable + this._scoreUnplayable; + const moved = previousMoved + this._scoreMoved; + const rest = previousRest + this._scoreRest; + + // candidates are interchangeable for later slices if all continuing groups agree + let slot = -1; + for (let c = 0; c < candidateCount && slot < 0; c++) { + let same = true; + for (let a = activeStart; a < activeEnd && same; a++) { + const g = this._activeGroups[a]; + if (this._groupLast[g] > t && cDeltas[c * activeLength + (a - activeStart)] !== groupDelta[g]) { + same = false; + } + } + if (same) { + slot = c; + } + } + + let write = -1; + if (slot >= 0) { + if (TabFingeringRun._isBetter(unplayable, moved, rest, cUnplayable[slot], cMoved[slot], cRest[slot])) { + write = slot; + } + } else if (candidateCount < beamWidth) { + write = candidateCount; + candidateCount++; + if (cUnplayable.length < candidateCount) { + cUnplayable.push(0); + cMoved.push(0); + cRest.push(0); + cCenter.push(0); + cBack.push(0); + cSequence.push(0); + } + while (cDeltas.length < candidateCount * activeLength) { + cDeltas.push(0); + } + } else { + let worst = 0; + for (let c = 1; c < candidateCount; c++) { + if ( + TabFingeringRun._isBetter( + cUnplayable[worst], + cMoved[worst], + cRest[worst], + cUnplayable[c], + cMoved[c], + cRest[c] + ) || + (TabFingeringRun._isEqual( + cUnplayable[worst], + cMoved[worst], + cRest[worst], + cUnplayable[c], + cMoved[c], + cRest[c] + ) && + cSequence[c] > cSequence[worst]) + ) { + worst = c; + } + } + if (TabFingeringRun._isBetter(unplayable, moved, rest, cUnplayable[worst], cMoved[worst], cRest[worst])) { + write = worst; + } + } + + if (write >= 0) { + cUnplayable[write] = unplayable; + cMoved[write] = moved; + cRest[write] = rest; + cCenter[write] = this._scoreCenter; + cBack[write] = previousState; + cSequence[write] = sequence; + for (let a = activeStart; a < activeEnd; a++) { + cDeltas[write * activeLength + (a - activeStart)] = groupDelta[this._activeGroups[a]]; + } + } + sequence++; + + // next combination of the new groups' options + let n = newGroups.length - 1; + while (n >= 0) { + const g = newGroups[n]; + choice[n]++; + if (choice[n] < this._groupOptionBase[g + 1] - this._groupOptionBase[g]) { + break; + } + choice[n] = 0; + n--; + } + if (n < 0) { + done = true; + } + } + } + + // commit the candidates best first + stateBase.push(stUnplayable.length); + stateCount.push(candidateCount); + const committed: boolean[] = new Array(candidateCount).fill(false); + for (let k = 0; k < candidateCount; k++) { + let best = -1; + for (let c = 0; c < candidateCount; c++) { + if (committed[c]) { + continue; + } + if ( + best < 0 || + TabFingeringRun._isBetter(cUnplayable[c], cMoved[c], cRest[c], cUnplayable[best], cMoved[best], cRest[best]) || + (TabFingeringRun._isEqual(cUnplayable[c], cMoved[c], cRest[c], cUnplayable[best], cMoved[best], cRest[best]) && + cSequence[c] < cSequence[best]) + ) { + best = c; + } + } + committed[best] = true; + stUnplayable.push(cUnplayable[best]); + stMoved.push(cMoved[best]); + stRest.push(cRest[best]); + stCenter.push(cCenter[best]); + stBack.push(cBack[best]); + stDeltaBase.push(stDeltas.length); + for (let a = 0; a < activeLength; a++) { + stDeltas.push(cDeltas[best * activeLength + a]); + } + } + } + + // follow the best path back, each group takes the delta chosen in its first slice + const result: number[] = new Array(this._groupCount).fill(0); + let state = sliceCount > 0 ? stateBase[sliceCount - 1] : -1; + for (let t = sliceCount - 1; t >= 0 && state >= 0; t--) { + const activeStart = this._activeBase[t]; + const activeEnd = this._activeBase[t + 1]; + for (let a = activeStart; a < activeEnd; a++) { + const g = this._activeGroups[a]; + if (this._groupFirst[g] === t) { + result[g] = stDeltas[stDeltaBase[state] + (a - activeStart)]; + } + } + state = stBack[state]; + } + return result; + } + + private static _isBetter( + unplayableA: number, + movedA: number, + restA: number, + unplayableB: number, + movedB: number, + restB: number + ): boolean { + if (unplayableA !== unplayableB) { + return unplayableA < unplayableB; + } + if (movedA !== movedB) { + return movedA < movedB; + } + return restA < restB; + } + + private static _isEqual( + unplayableA: number, + movedA: number, + restA: number, + unplayableB: number, + movedB: number, + restB: number + ): boolean { + return unplayableA === unplayableB && movedA === movedB && restA === restB; + } + + // results of _scoreSlice + private _scoreUnplayable: number = 0; + private _scoreMoved: number = 0; + private _scoreRest: number = 0; + private _scoreCenter: number = -1; + + private _scoreSlice(t: number, groupDelta: number[], previousCenter: number, gapQuarters: number): void { + const options = this._options; + let unplayable = 0; + let moved = 0; + let rest = 0; + let usedStrings = 0; + let frettedCount = 0; + let fretSum = 0; + let minFret = 0; + let maxFret = 0; + + for (let k = this._sliceNoteBase[t]; k < this._sliceNoteBase[t + 1]; k++) { + const i = this._sliceNotes[k]; + const delta = groupDelta[this._group[i]]; + const str = this._originalString[i] + delta; + if (!this._evaluate(i, str)) { + unplayable++; + } + if (delta !== 0) { + moved++; + } + const stringBit = 1 << (str - 1); + if ((usedStrings & stringBit) !== 0) { + unplayable++; + } else { + usedStrings |= stringBit; + } + + const kind = this._kind[i]; + if (kind === TabFingeringRun._kindDead || this._evalNode >= 0) { + continue; + } + if ((this._evalFlags & TabFingeringSegment.flagAsArtificial) !== 0) { + rest += options.asArtificialPenalty; + } + const fret = this._evalFret; + if (fret === 0) { + rest += options.openStringBonus; + } else if (fret > 0) { + if (frettedCount === 0 || fret < minFret) { + minFret = fret; + } + if (frettedCount === 0 || fret > maxFret) { + maxFret = fret; + } + frettedCount++; + fretSum += fret; + } + if (fret > options.highFretThreshold) { + rest += (fret - options.highFretThreshold) * options.highFretPenaltyWeight; + } + } + + for (let k = this._soundBase[t]; k < this._soundBase[t + 1]; k++) { + const i = this._soundNotes[k]; + const str = this._originalString[i] + groupDelta[this._group[i]]; + if ((usedStrings & (1 << (str - 1))) !== 0) { + rest += options.occupancyPenalty; + } + } + + let center = previousCenter; + if (frettedCount > 0) { + const span = maxFret - minFret; + rest += span * options.spanWeight; + if (span > options.maxSpan) { + rest += (span - options.maxSpan) * options.overSpanPenalty; + } + center = fretSum / frettedCount; + if (previousCenter >= 0) { + rest += (Math.abs(center - previousCenter) * options.handMovementWeight) / (1 + gapQuarters); + } + } + + this._scoreUnplayable = unplayable; + this._scoreMoved = moved; + this._scoreRest = rest; + this._scoreCenter = center; + } +} diff --git a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts new file mode 100644 index 0000000000..b922030819 --- /dev/null +++ b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts @@ -0,0 +1,197 @@ +import { AlphaTexImporter } from '@coderline/alphatab/importer/AlphaTexImporter'; +import type { Note } from '@coderline/alphatab/model/Note'; +import type { Score } from '@coderline/alphatab/model/Score'; +import type { Staff } from '@coderline/alphatab/model/Staff'; +import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; +import { TabFingeringSolver } from '@coderline/alphatab/rendering/utils/TabFingeringSolver'; +import { Settings } from '@coderline/alphatab/Settings'; +import { describe, expect, it } from 'vitest'; + +describe('TabFingeringSolverTest', () => { + /** + * @static + */ + function parseTex(tex: string): Score { + const importer = new AlphaTexImporter(); + importer.logErrors = true; + importer.initFromString(tex, new Settings()); + return importer.readScore(); + } + + /** + * @static + */ + function solveStaff(staff: Staff): (TabFingeringSegment | null)[] { + const segments: (TabFingeringSegment | null)[] = []; + let start = 0; + while (start < staff.bars.length) { + const end = TabFingeringSolver.segmentEnd(staff, start); + const segment = TabFingeringSolver.solve(staff, start, end); + for (let b = start; b <= end; b++) { + segments.push(segment); + } + start = end + 1; + } + return segments; + } + + /** + * Describes the displayed position of every note as `fret.string` in alphaTex string numbering + * plus `*` for moved, `!` for unplayable and `A` for natural harmonics shown as artificial ones. + * @static + */ + function display(staff: Staff): string[][] { + const segments = solveStaff(staff); + const stringCount = staff.tuning.length; + const bars: string[][] = []; + for (const bar of staff.bars) { + const result: string[] = []; + const segment = segments[bar.index]; + for (const voice of bar.voices) { + for (const beat of voice.beats) { + for (const note of beat.notes) { + result.push(describeNote(note, segment, stringCount)); + } + } + } + bars.push(result); + } + return bars; + } + + /** + * @static + */ + function describeNote(note: Note, segment: TabFingeringSegment | null, stringCount: number): string { + if (segment === null) { + return `${note.fret - note.beat.voice.bar.staff.transpositionPitch}.${stringCount - note.string + 1}`; + } + const flags = segment.getFlags(note); + let s = ''; + const node = segment.getNode(note); + if (node >= 0) { + s += `<${TabFingeringSolver.naturalNodeValues[node]}>`; + } else { + s += `${segment.getFret(note)}`; + } + s += `.${stringCount - segment.getString(note) + 1}`; + if ((flags & TabFingeringSegment.flagMoved) !== 0) { + s += '*'; + } + if ((flags & TabFingeringSegment.flagUnplayable) !== 0) { + s += '!'; + } + if ((flags & TabFingeringSegment.flagAsArtificial) !== 0) { + s += 'A'; + } + return s; + } + + /** + * @static + */ + function staffOf(tex: string): Staff { + return parseTex(tex).tracks[0].staves[0]; + } + + it('is inactive without transposition and on percussion', () => { + expect(TabFingeringSolver.isActive(staffOf('3.3'))).toBe(false); + expect(TabFingeringSolver.isActive(staffOf('\\transpose -4 3.3'))).toBe(true); + const percussion = staffOf('\\transpose -4 3.3'); + percussion.isPercussion = true; + expect(TabFingeringSolver.isActive(percussion)).toBe(false); + }); + + it('keeps strings when the shifted frets are playable', () => { + const staff = staffOf('\\transpose 2 3.3 5.2 0.1 | 12.6'); + expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); + expect(display(staff)).toEqual([['5.3', '7.2', '2.1'], ['14.6']]); + }); + + it('moves notes below the open string to lower strings', () => { + const staff = staffOf('\\transpose -4 3.5 2.4 5.3 0.6'); + expect(display(staff)).toEqual([['4.6*', '3.5*', '1.3', '-4.6!']]); + }); + + it('places chord notes on distinct strings', () => { + const staff = staffOf('\\transpose -4 (0.1 0.2)'); + expect(display(staff)).toEqual([['1.2*', '0.3*']]); + }); + + it('keeps tied notes on the string of their origin', () => { + const staff = staffOf('\\transpose -4 3.5 3.5 | -.5 2.4'); + expect(TabFingeringSolver.segmentEnd(staff, 0)).toBe(1); + expect(TabFingeringSolver.segmentStart(staff, 1)).toBe(0); + expect(TabFingeringSolver.isSegmentStart(staff, 1)).toBe(false); + expect(display(staff)).toEqual([ + ['4.6*', '4.6*'], + ['4.6*', '3.5*'] + ]); + }); + + it('moves hammer-ons and slides as a whole', () => { + expect(display(staffOf('\\transpose -4 2.3{h} 4.3 2.3{ss} 4.3'))).toEqual([ + ['3.4*', '5.4*', '3.4*', '5.4*'] + ]); + }); + + it('allows pull-offs to open strings', () => { + const staff = staffOf('\\transpose 2 6.3{h} 2.3'); + expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); + }); + + it('does not bend on open strings', () => { + expect(display(staffOf('\\transpose -4 4.3{b (0 4)}'))).toEqual([['5.4*']]); + }); + + it('remaps natural harmonics to nodes of the transposed pitch', () => { + const sameString = staffOf('\\transpose 7 12.6{nh}'); + expect(TabFingeringSolver.solve(sameString, 0, 0)).toBe(null); + const note = sameString.bars[0].voices[0].beats[0].notes[0]; + expect(TabFingeringSolver.naturalNodeValues[TabFingeringSolver.findNaturalNodeOnModelString(note)]).toBe(7); + + expect(display(staffOf('\\transpose -4 12.5{nh}'))).toEqual([['1.6*A']]); + }); + + it('ignores the fret of dead notes', () => { + const staff = staffOf('\\transpose -4 0.6{x}'); + expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); + }); + + it('requires a playable trill fret', () => { + expect(TabFingeringSolver.solve(staffOf('\\transpose -5 5.3{tr 7 16}'), 0, 0)).toBe(null); + expect(display(staffOf('\\transpose -6 5.3{tr 7 16}'))).toEqual([['4.4*']]); + }); + + it('handles re-entrant tunings', () => { + expect(display(staffOf('\\tuning A4 E4 C4 G4 \\transpose -6 2.1'))).toEqual([['1.2*']]); + }); + + it('handles bass tunings', () => { + expect(display(staffOf('\\tuning G2 D2 A1 E1 \\transpose -1 0.3 0.4'))).toEqual([['4.4*', '-1.4!']]); + }); + + it('counts the fret limit from the capo', () => { + expect(display(staffOf('\\capo 2 \\transpose 3 20.1'))).toEqual([['23.1!']]); + expect(display(staffOf('\\capo 2 \\transpose 2 20.1'))).toEqual([['22.1']]); + }); + + it('avoids collisions across voices', () => { + const staff = staffOf('\\transpose -4 \\voice 0.1 \\voice 1.2'); + expect(display(staff)).toEqual([['1.2*', '1.3*']]); + }); + + it('keeps grace notes connected to their main note', () => { + expect(display(staffOf('\\transpose -4 2.3{ss} {gr ob} 4.3'))).toEqual([['3.4*', '5.4*']]); + }); + + it('fingers repeated bars identically', () => { + const result = display(staffOf('\\transpose -4 3.5 2.4 0.3 | 3.5 2.4 0.3')); + expect(result[1]).toEqual(result[0]); + }); + + it('is deterministic', () => { + const tex = '\\transpose -4 (0.1 0.2 0.3) (3.5 2.4) 0.6 | (0.1 1.2) 3.3{h} 5.3'; + expect(display(staffOf(tex))).toEqual(display(staffOf(tex))); + }); +}); From 3748d2273ffe1c1ccd7cb2eef68700a746825a9b Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:30:21 +0100 Subject: [PATCH 04/12] feat(rendering): show transposed tabs on playable strings When a staff with tablature is transposed (notation.transpositionPitches, \transpose), the tab no longer just subtracts the transposition from the fret. TabBarRenderer resolves the fingering of the segment of linked bars once per layout via TabFingeringSolver and all tab glyphs read the displayed string and fret from it: fret numbers, note lines, staff line gaps, ties, slurs, bends, brushes, flags and the harmonic labels. The model stays untouched. Notes which fit on no string keep their string and the out-of-range fret and are painted in the new RenderingResources.tabUnplayableFretColor. String-number circles show the displayed string and left-hand finger numbers of re-fingered notes are hidden. A partial render restarts at the first bar of the affected segment. --- packages/alphatab/src/RenderingResources.ts | 7 + .../src/generated/RenderingResourcesJson.ts | 6 + .../generated/RenderingResourcesSerializer.ts | 6 +- .../src/generated/SerializerSchema.ts | 2 +- .../alphatab/src/rendering/TabBarRenderer.ts | 224 +++++++++++++++++- .../rendering/effects/FingeringEffectInfo.ts | 11 +- .../rendering/effects/HarmonicsEffectInfo.ts | 22 +- .../rendering/glyphs/FingeringGroupGlyph.ts | 52 +++- .../src/rendering/glyphs/NoteNumberGlyph.ts | 51 +++- .../src/rendering/glyphs/ScoreBeatGlyph.ts | 2 +- .../glyphs/StringNumberContainerGlyph.ts | 12 +- .../rendering/glyphs/TabBeatContainerGlyph.ts | 8 +- .../src/rendering/glyphs/TabBeatGlyph.ts | 4 +- .../src/rendering/glyphs/TabBendGlyph.ts | 12 +- .../src/rendering/glyphs/TabBrushGlyph.ts | 8 +- .../src/rendering/glyphs/TabNoteChordGlyph.ts | 35 ++- .../src/rendering/glyphs/TabSlurGlyph.ts | 9 +- .../src/rendering/glyphs/TabTieGlyph.ts | 16 +- .../rendering/layout/VerticalLayoutBase.ts | 7 +- .../src/rendering/utils/ElementStyleHelper.ts | 13 + .../src/rendering/utils/TabFingeringSolver.ts | 70 +++++- .../alphatab/test/generated/SerializerFill.ts | 3 + .../TabFingeringPartialUpdate.test.ts | 88 +++++++ .../test/rendering/TabFingeringSolver.test.ts | 4 +- 24 files changed, 601 insertions(+), 71 deletions(-) create mode 100644 packages/alphatab/test/rendering/TabFingeringPartialUpdate.test.ts diff --git a/packages/alphatab/src/RenderingResources.ts b/packages/alphatab/src/RenderingResources.ts index cf393b5e7e..d0cd62a95c 100644 --- a/packages/alphatab/src/RenderingResources.ts +++ b/packages/alphatab/src/RenderingResources.ts @@ -349,6 +349,13 @@ export class RenderingResources { */ public scoreInfoColor: Color = new Color(0, 0, 0, 0xff); + /** + * The color of tab fret numbers which cannot be played on the tuning of the staff after transposition. + * @defaultValue `rgb(200, 0, 0)` + * @since 1.10.0 + */ + public tabUnplayableFretColor: Color = new Color(200, 0, 0, 0xff); + public constructor() { for (const [k, v] of RenderingResources.defaultFonts) { this.elementFonts.set(k, v.withSize(v.size)); diff --git a/packages/alphatab/src/generated/RenderingResourcesJson.ts b/packages/alphatab/src/generated/RenderingResourcesJson.ts index f4ddafe3d1..e546302c01 100644 --- a/packages/alphatab/src/generated/RenderingResourcesJson.ts +++ b/packages/alphatab/src/generated/RenderingResourcesJson.ts @@ -199,4 +199,10 @@ export interface RenderingResourcesJson { * @since 0.9.6 */ scoreInfoColor?: ColorJson; + /** + * The color of tab fret numbers which cannot be played on the tuning of the staff after transposition. + * @defaultValue `rgb(200, 0, 0)` + * @since 1.10.0 + */ + tabUnplayableFretColor?: ColorJson; } diff --git a/packages/alphatab/src/generated/RenderingResourcesSerializer.ts b/packages/alphatab/src/generated/RenderingResourcesSerializer.ts index 1ebcbe3e41..42851636e3 100644 --- a/packages/alphatab/src/generated/RenderingResourcesSerializer.ts +++ b/packages/alphatab/src/generated/RenderingResourcesSerializer.ts @@ -16,7 +16,7 @@ import type { IObjectWriter } from "@coderline/alphatab/io/IObjectWriter"; * @internal */ export class RenderingResourcesSerializer { - private static readonly _fields: RecordFields = new RecordFields(["smuflfontfamilyname", "engravingsettings", "copyrightfont", "titlefont", "subtitlefont", "wordsfont", "timerfont", "directionsfont", "fretboardnumberfont", "fingeringfont", "inlinefingeringfont", "markerfont", "effectfont", "barnumberfont", "elementfonts", "numberednotationfont", "numberednotationgracefont", "tablaturefont", "gracefont", "stafflinecolor", "barseparatorcolor", "barnumbercolor", "mainglyphcolor", "secondaryglyphcolor", "scoreinfocolor"]); + private static readonly _fields: RecordFields = new RecordFields(["smuflfontfamilyname", "engravingsettings", "copyrightfont", "titlefont", "subtitlefont", "wordsfont", "timerfont", "directionsfont", "fretboardnumberfont", "fingeringfont", "inlinefingeringfont", "markerfont", "effectfont", "barnumberfont", "elementfonts", "numberednotationfont", "numberednotationgracefont", "tablaturefont", "gracefont", "stafflinecolor", "barseparatorcolor", "barnumbercolor", "mainglyphcolor", "secondaryglyphcolor", "scoreinfocolor", "tabunplayablefretcolor"]); public static read(obj: RenderingResources, reader: IObjectReader): void { reader.readRecord(RenderingResourcesSerializer._fields, (id, k, rr) => RenderingResourcesSerializer._readField(obj, id, rr, false)); } @@ -101,6 +101,9 @@ export class RenderingResourcesSerializer { case 24: obj.scoreInfoColor = Color.fromJson(r.readValue())!; return true; + case 25: + obj.tabUnplayableFretColor = Color.fromJson(r.readValue())!; + return true; } return false; } @@ -148,6 +151,7 @@ export class RenderingResourcesSerializer { w.valueField(22, Color.toJson(obj.mainGlyphColor)); w.valueField(23, Color.toJson(obj.secondaryGlyphColor)); w.valueField(24, Color.toJson(obj.scoreInfoColor)); + w.valueField(25, Color.toJson(obj.tabUnplayableFretColor)); w.endObject(); } } diff --git a/packages/alphatab/src/generated/SerializerSchema.ts b/packages/alphatab/src/generated/SerializerSchema.ts index 375b6fbb4d..82ce5af23b 100644 --- a/packages/alphatab/src/generated/SerializerSchema.ts +++ b/packages/alphatab/src/generated/SerializerSchema.ts @@ -12,5 +12,5 @@ export class SerializerSchema { /** * A hash of the field ids, keys and types of all serialized classes (50 classes). */ - public static readonly fingerprint: number = 0xacc550b1; + public static readonly fingerprint: number = 0xa8bdf264; } diff --git a/packages/alphatab/src/rendering/TabBarRenderer.ts b/packages/alphatab/src/rendering/TabBarRenderer.ts index dc633a08f0..92e0bec6ef 100644 --- a/packages/alphatab/src/rendering/TabBarRenderer.ts +++ b/packages/alphatab/src/rendering/TabBarRenderer.ts @@ -2,7 +2,7 @@ import { BarSubElement } from '@coderline/alphatab/model/Bar'; import { type Beat, BeatSubElement } from '@coderline/alphatab/model/Beat'; import type { ElementDisplay } from '@coderline/alphatab/model/ElementDisplay'; import { GraceType } from '@coderline/alphatab/model/GraceType'; -import type { Note } from '@coderline/alphatab/model/Note'; +import { Note } from '@coderline/alphatab/model/Note'; import type { BarNumberDisplay } from '@coderline/alphatab/model/RenderStylesheet'; import type { Voice } from '@coderline/alphatab/model/Voice'; import { TabRhythmMode } from '@coderline/alphatab/NotationSettings'; @@ -25,6 +25,8 @@ import { BeamDirection } from '@coderline/alphatab/rendering/utils/BeamDirection import type { BeamingHelper } from '@coderline/alphatab/rendering/utils/BeamingHelper'; import { ElementStyleHelper } from '@coderline/alphatab/rendering/utils/ElementStyleHelper'; import type { ScrambledPath } from '@coderline/alphatab/rendering/utils/ScrambledPath'; +import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; +import { TabFingeringSolver } from '@coderline/alphatab/rendering/utils/TabFingeringSolver'; /** * This BarRenderer renders a bar using guitar tablature notation @@ -137,7 +139,211 @@ export class TabBarRenderer extends LineBarRenderer { } public override getNoteLine(note: Note): number { - return this.bar.staff.tuning.length - note.string; + return this.bar.staff.tuning.length - this.getDisplayString(note); + } + + /** + * The display fingering of the transposed segment this bar belongs to, null if all notes + * keep their model string. + */ + public fingering: TabFingeringSegment | null = null; + + /** + * The last bar of the segment this bar belongs to when all its notes keep their model string, -1 otherwise. + */ + public identityUntilBarIndex: number = -1; + + private _isFingeringActive: boolean = false; + + private _resolveFingering(): void { + const staff = this.bar.staff; + this.fingering = null; + this.identityUntilBarIndex = -1; + this._isFingeringActive = TabFingeringSolver.isActive(staff); + if (!this._isFingeringActive) { + return; + } + + const barIndex = this.bar.index; + const previous = this.previousRenderer; + if (previous instanceof TabBarRenderer) { + const previousFingering = previous.fingering; + if (previousFingering !== null && previousFingering.covers(barIndex)) { + this.fingering = previousFingering; + return; + } + if (previous.identityUntilBarIndex >= barIndex) { + this.identityUntilBarIndex = previous.identityUntilBarIndex; + return; + } + } + + const lastBarIndex = TabFingeringSolver.segmentEnd(staff, barIndex); + this.fingering = TabFingeringSolver.solve(staff, barIndex, lastBarIndex); + if (this.fingering === null) { + this.identityUntilBarIndex = lastBarIndex; + } + } + + protected override createBeatGlyphs(): void { + this._resolveFingering(); + super.createBeatGlyphs(); + } + + private _fingeringFor(note: Note): TabFingeringSegment | null { + const bar = note.beat.voice.bar; + const own = this.fingering; + if (own !== null && own.covers(bar.index)) { + return own; + } + if (bar === this.bar) { + return null; + } + const renderer = this.scoreRenderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar); + if (renderer instanceof TabBarRenderer) { + const fingering = renderer.fingering; + if (fingering !== null && fingering.covers(bar.index)) { + return fingering; + } + } + return null; + } + + /** + * The string (1 = lowest) on which the note is shown in this tab. + */ + public getDisplayString(note: Note): number { + if (!this._isFingeringActive || !note.isStringed) { + return note.string; + } + const fingering = this._fingeringFor(note); + return fingering !== null ? fingering.getString(note) : note.string; + } + + /** + * The fret shown for the note: the natural harmonic node for natural harmonics, the base fret otherwise. + */ + public getDisplayFret(note: Note): number { + const staff = note.beat.voice.bar.staff; + const isNaturalHarmonic = TabFingeringSolver.isNaturalHarmonic(note); + if (!this._isFingeringActive || !note.isStringed) { + return (isNaturalHarmonic ? note.harmonicValue : note.fret) - staff.transpositionPitch; + } + const fingering = this._fingeringFor(note); + if (fingering === null) { + if (isNaturalHarmonic) { + const modelStringNode = TabFingeringSolver.findNaturalNodeOnModelString(note); + return modelStringNode >= 0 + ? TabFingeringSolver.naturalNodeValues[modelStringNode] + : note.harmonicValue - staff.transpositionPitch; + } + return note.fret - staff.transpositionPitch; + } + const node = fingering.getNode(note); + return node >= 0 ? TabFingeringSolver.naturalNodeValues[node] : fingering.getFret(note); + } + + /** + * The combination of {@link TabFingeringSegment} flags describing how the note differs from the model. + */ + public getDisplayFlags(note: Note): number { + if (!this._isFingeringActive || !note.isStringed) { + return 0; + } + const fingering = this._fingeringFor(note); + return fingering !== null ? fingering.getFlags(note) : 0; + } + + /** + * The fret of the trill target on the displayed string of the note. + */ + public getDisplayTrillFret(note: Note): number { + const staff = note.beat.voice.bar.staff; + return ( + note.trillValue - + staff.transpositionPitch - + (staff.capo + Note.getStringTuning(staff, this.getDisplayString(note))) + ); + } + + /** + * The stringed note of the beat shown on the highest string. + */ + public getDisplayMaxStringNote(beat: Beat): Note | null { + if (!this._isFingeringActive) { + return beat.maxStringNote; + } + let result: Note | null = null; + let resultString = 0; + for (const note of beat.notes) { + if (!note.isStringed) { + continue; + } + const str = this.getDisplayString(note); + if (result === null || str > resultString) { + result = note; + resultString = str; + } + } + return result; + } + + /** + * The stringed note of the beat shown on the lowest string. + */ + public getDisplayMinStringNote(beat: Beat): Note | null { + if (!this._isFingeringActive) { + return beat.minStringNote; + } + let result: Note | null = null; + let resultString = 0; + for (const note of beat.notes) { + if (!note.isStringed) { + continue; + } + const str = this.getDisplayString(note); + if (result === null || str < resultString) { + result = note; + resultString = str; + } + } + return result; + } + + /** + * The string on which the given note is shown in the tab of its staff, for renderers of other notations. + */ + public static resolveDisplayString(renderer: BarRendererBase, note: Note): number { + if (!TabFingeringSolver.isActive(note.beat.voice.bar.staff)) { + return note.string; + } + const tab = TabBarRenderer._tabRendererOf(renderer, note); + return tab !== null ? tab.getDisplayString(note) : note.string; + } + + // a renderer is registered in the layout only after its own layout + private static _tabRendererOf(renderer: BarRendererBase, note: Note): TabBarRenderer | null { + const bar = note.beat.voice.bar; + if (renderer instanceof TabBarRenderer && renderer.bar === bar) { + return renderer; + } + const tab = renderer.scoreRenderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar); + return tab instanceof TabBarRenderer ? tab : null; + } + + /** + * Whether the tab of the note's staff shows it on another string or as open string, so left-hand + * fingerings of the model do not apply to it. + */ + public static isFingeringChanged(renderer: BarRendererBase, note: Note): boolean { + if (!note.isStringed || !TabFingeringSolver.isActive(note.beat.voice.bar.staff)) { + return false; + } + const tab = TabBarRenderer._tabRendererOf(renderer, note); + if (tab === null) { + return false; + } + return (tab.getDisplayFlags(note) & TabFingeringSegment.flagMoved) !== 0 || tab.getDisplayFret(note) === 0; } public minString = Number.NaN; @@ -295,7 +501,7 @@ export class TabBarRenderer extends LineBarRenderer { const noteGlyphs = noteNumbers.noteGlyphs; for (let k = 0, nk = noteGlyphs.length; k < nk; k++) { const g = noteGlyphs[k]; - const str = g.note.string; + const str = g.displayString; if (!g.isEmpty && noteNumbers.getNoteGlyphForString(str) === g) { const lineIdx = tuningLen - str; if (lineIdx >= 0 && lineIdx < drawnLineCount) { @@ -342,7 +548,7 @@ export class TabBarRenderer extends LineBarRenderer { const noteGlyphs = noteNumbers.noteGlyphs; for (let k = 0, nk = noteGlyphs.length; k < nk; k++) { const g = noteGlyphs[k]; - const str = g.note.string; + const str = g.displayString; if (!g.isEmpty && noteNumbers.getNoteGlyphForString(str) === g) { const lineIdx = tuningLen - str; if (lineIdx >= 0 && lineIdx < drawnLineCount) { @@ -402,8 +608,10 @@ export class TabBarRenderer extends LineBarRenderer { // Per-beat half-line overflow, not bar-wide. Strings are 1-indexed: top = tuning.length, bottom = 1. const beat = beatContainer.beat; const stringCount = this.bar.staff.tuning.length; - const hasTop = beat.maxStringNote !== null && beat.maxStringNote.string === stringCount; - const hasBottom = beat.minStringNote !== null && beat.minStringNote.string === 1; + const maxStringNote = this.getDisplayMaxStringNote(beat); + const minStringNote = this.getDisplayMinStringNote(beat); + const hasTop = maxStringNote !== null && this.getDisplayString(maxStringNote) === stringCount; + const hasBottom = minStringNote !== null && this.getDisplayString(minStringNote) === 1; if (!hasTop && !hasBottom) { return; } @@ -516,7 +724,7 @@ export class TabBarRenderer extends LineBarRenderer { } protected override getFlagTopY(beat: Beat, direction: BeamDirection): number { - const maxNote = beat.maxStringNote; + const maxNote = this.getDisplayMaxStringNote(beat); const position = direction === BeamDirection.Up ? NoteYPosition.TopWithStem : NoteYPosition.StemDown; if (maxNote) { return this.getNoteY(maxNote, position); @@ -526,7 +734,7 @@ export class TabBarRenderer extends LineBarRenderer { } protected override getFlagBottomY(beat: Beat, direction: BeamDirection): number { - const maxNote = beat.minStringNote; + const maxNote = this.getDisplayMinStringNote(beat); const position = direction === BeamDirection.Up ? NoteYPosition.StemUp : NoteYPosition.BottomWithStem; if (maxNote) { diff --git a/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts b/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts index 8bb3bd1362..d6a9e0e765 100644 --- a/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts @@ -2,6 +2,7 @@ import type { Beat } from '@coderline/alphatab/model/Beat'; import { Fingers } from '@coderline/alphatab/model/Fingers'; import type { Note } from '@coderline/alphatab/model/Note'; import { FingeringMode, NotationElement } from '@coderline/alphatab/NotationSettings'; +import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import type { BarRendererBase } from '@coderline/alphatab/rendering/BarRendererBase'; import { EffectBarGlyphSizing } from '@coderline/alphatab/rendering/EffectBarGlyphSizing'; import { EffectBandPlacementCategory, type EffectInfo } from '@coderline/alphatab/rendering/EffectInfo'; @@ -30,7 +31,15 @@ export const fingeringEffectInfo: EffectInfo = { if (beat.notes.length !== 1) { return false; } - return beat.notes[0].isFingering; + const note = beat.notes[0]; + if ( + note.leftHandFinger !== Fingers.Unknown && + renderer instanceof TabBarRenderer && + TabBarRenderer.isFingeringChanged(renderer, note) + ) { + return false; + } + return note.isFingering; }, createNewGlyph: (renderer: BarRendererBase, beat: Beat): EffectGlyph => { let finger: Fingers = Fingers.Unknown; diff --git a/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts b/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts index bb4476e3f9..78f9846730 100644 --- a/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts @@ -5,9 +5,10 @@ import { NotationElement } from '@coderline/alphatab/NotationSettings'; import type { BarRendererBase } from '@coderline/alphatab/rendering/BarRendererBase'; import { EffectBarGlyphSizing } from '@coderline/alphatab/rendering/EffectBarGlyphSizing'; import { EffectBandPlacementCategory, type EffectInfo } from '@coderline/alphatab/rendering/EffectInfo'; -import { createNoteShouldCreateGlyph } from '@coderline/alphatab/rendering/effects/NoteEffectInfoBase'; import type { EffectGlyph } from '@coderline/alphatab/rendering/glyphs/EffectGlyph'; import { LineRangedGlyph } from '@coderline/alphatab/rendering/glyphs/LineRangedGlyph'; +import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; +import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; /** * @internal @@ -51,6 +52,20 @@ function harmonicEffectId(harmonicType: HarmonicType): string { } } +/** + * Natural harmonics without a node on the transposed tab are shown as artificial harmonics. + */ +function displayedHarmonicType(renderer: BarRendererBase, note: Note): HarmonicType { + if ( + note.harmonicType === HarmonicType.Natural && + renderer instanceof TabBarRenderer && + (renderer.getDisplayFlags(note) & TabFingeringSegment.flagAsArtificial) !== 0 + ) { + return HarmonicType.Artificial; + } + return note.harmonicType; +} + /** * @internal */ @@ -60,9 +75,8 @@ export function createHarmonicsEffectInfo(harmonicType: HarmonicType): EffectInf notationElement: NotationElement.EffectHarmonics, hideOnMultiTrack: false, sizingMode: EffectBarGlyphSizing.GroupedOnBeat, - shouldCreateGlyph: createNoteShouldCreateGlyph( - (note: Note): boolean => note.isHarmonic && note.harmonicType === harmonicType - ), + shouldCreateGlyph: (renderer: BarRendererBase, beat: Beat): boolean => + beat.notes.some(note => note.isHarmonic && displayedHarmonicType(renderer, note) === harmonicType), createNewGlyph: (_renderer: BarRendererBase, _beat: Beat): EffectGlyph => new LineRangedGlyph(harmonicToString(harmonicType), NotationElement.EffectHarmonics), canExpand: (_from: Beat, _to: Beat): boolean => true, diff --git a/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts b/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts index 188a35b478..5d6dfcde62 100644 --- a/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts @@ -10,6 +10,8 @@ import type { Settings } from '@coderline/alphatab/Settings'; import type { Beat } from '@coderline/alphatab/model/Beat'; import { Fingers } from '@coderline/alphatab/model/Fingers'; import { GeneralMidi } from '@coderline/alphatab/midi/GeneralMidi'; +import type { ICanvas } from '@coderline/alphatab/platform/ICanvas'; +import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; /** * @internal @@ -18,6 +20,11 @@ export class FingeringInfo { public line: number = 0; public symbols: MusicFontSymbol[]; public color: Color | undefined; + /** + * The notes of the left-hand fingers in {@link symbols}. + */ + public leftHandNotes: Note[] = []; + public otherSymbolCount: number = 0; public constructor(line: number, symbols: MusicFontSymbol[]) { this.line = line; @@ -30,6 +37,7 @@ export class FingeringInfo { */ export class FingeringGroupGlyph extends GlyphGroup { private _infos: Map = new Map(); + private _glyphInfos: FingeringInfo[] = []; public constructor() { super(0, 0); @@ -72,7 +80,7 @@ export class FingeringGroupGlyph extends GlyphGroup { true ); if (symbolLeft !== MusicFontSymbol.None) { - this._addFinger(note, symbolLeft); + this._addFinger(note, symbolLeft, true); } const symbolRight = FingeringGroupGlyph.fingerToMusicFontSymbol( this.renderer.settings, @@ -81,7 +89,7 @@ export class FingeringGroupGlyph extends GlyphGroup { false ); if (symbolRight !== MusicFontSymbol.None) { - this._addFinger(note, symbolRight); + this._addFinger(note, symbolRight, false); } } @@ -153,18 +161,51 @@ export class FingeringGroupGlyph extends GlyphGroup { } } - private _addFinger(note: Note, symbol: MusicFontSymbol) { + private _addFinger(note: Note, symbol: MusicFontSymbol, isLeftHand: boolean) { const sr = this.renderer as ScoreBarRenderer; const steps: number = sr.getNoteSteps(note); + let info: FingeringInfo; if (!this._infos.has(steps)) { - const info = new FingeringInfo(steps, [symbol]); + info = new FingeringInfo(steps, [symbol]); info.color = ElementStyleHelper.noteColor(sr.resources, NoteSubElement.StandardNotationEffects, note); this._infos.set(steps, info); } else { - const info = this._infos.get(steps)!; + info = this._infos.get(steps)!; info.symbols.push(symbol); } + if (isLeftHand) { + info.leftHandNotes.push(note); + } else { + info.otherSymbolCount++; + } + } + + public override paint(cx: number, cy: number, canvas: ICanvas): void { + const glyphs = this.glyphs; + if (!glyphs) { + return; + } + const x = cx + this.x; + const y = cy + this.y; + for (let i = 0; i < glyphs.length; i++) { + if (!this._isReFingered(this._glyphInfos[i])) { + glyphs[i].paint(x, y, canvas); + } + } + } + + // resolved on paint: the tab of the bar is laid out after this staff + private _isReFingered(info: FingeringInfo): boolean { + if (info.otherSymbolCount > 0 || info.leftHandNotes.length === 0) { + return false; + } + for (const note of info.leftHandNotes) { + if (!TabBarRenderer.isFingeringChanged(this.renderer, note)) { + return false; + } + } + return true; } public override doLayout(): void { @@ -178,6 +219,7 @@ export class FingeringGroupGlyph extends GlyphGroup { g.doLayout(); g.offsetY = g.height / 2; this.addGlyph(g); + this._glyphInfos.push(info); this.width = Math.max(this.width, g.width); } diff --git a/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts b/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts index 1b099a5d94..372db4191e 100644 --- a/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts @@ -1,4 +1,5 @@ import { BendType } from '@coderline/alphatab/model/BendType'; +import type { Color } from '@coderline/alphatab/model/Color'; import type { Font } from '@coderline/alphatab/model/Font'; import { HarmonicType } from '@coderline/alphatab/model/HarmonicType'; import { ModelUtils } from '@coderline/alphatab/model/ModelUtils'; @@ -9,6 +10,7 @@ import type { ICanvas } from '@coderline/alphatab/platform/ICanvas'; import { Glyph } from '@coderline/alphatab/rendering/glyphs/Glyph'; import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { ElementStyleHelper } from '@coderline/alphatab/rendering/utils/ElementStyleHelper'; +import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; import type { IBoundsLookupWriter } from '@coderline/alphatab/rendering/utils/IBoundsLookupWriter'; /** @@ -20,12 +22,20 @@ export class NoteNumberGlyph extends Glyph { private _trillNoteString: string | null = null; private _trillNoteStringWidth: number = 0; + private _isUnplayable: boolean = false; + public isEmpty: boolean = false; public noteStringWidth: number = 0; - public constructor(x: number, y: number, note: Note) { + /** + * The string (1 = lowest) on which the note is shown. + */ + public displayString: number; + + public constructor(x: number, y: number, note: Note, displayString: number) { super(x, y); this._note = note; + this.displayString = displayString; } public get note(): Note { @@ -46,11 +56,17 @@ export class NoteNumberGlyph extends Glyph { public override doLayout(): void { const n: Note = this._note; + const tr = this.renderer as TabBarRenderer; let fret: number; + let harmonicType = n.harmonicType; + let harmonicValue = n.harmonicValue; if (n.isStringed) { - fret = n.fret - n.beat.voice.bar.staff.transpositionPitch; - if (n.harmonicType === HarmonicType.Natural && n.harmonicValue !== 0) { - fret = n.harmonicValue - n.beat.voice.bar.staff.transpositionPitch; + fret = tr.getDisplayFret(n); + const flags = tr.getDisplayFlags(n); + this._isUnplayable = (flags & TabFingeringSegment.flagUnplayable) !== 0; + if ((flags & TabFingeringSegment.flagAsArtificial) !== 0) { + harmonicType = HarmonicType.Artificial; + harmonicValue = 12; } } else { const articulation = PercussionMapper.getArticulation(n); @@ -65,7 +81,7 @@ export class NoteNumberGlyph extends Glyph { this._noteString = n.isDead ? 'x' : fret.toString(); if (n.isGhost) { this._noteString = `(${this._noteString})`; - } else if (n.harmonicType === HarmonicType.Natural) { + } else if (harmonicType === HarmonicType.Natural) { // only first decimal char const i: number = this._noteString.indexOf(String.fromCharCode(46)); if (i >= 0) { @@ -78,20 +94,20 @@ export class NoteNumberGlyph extends Glyph { ((n.bendType === BendType.Bend || n.bendType === BendType.BendRelease) && this.renderer.settings.notation.isNotationElementVisible(NotationElement.TabNotesOnTiedBends)) ) { - this._noteString = `(${(n.tieOrigin!.fret - n.beat.voice.bar.staff.transpositionPitch).toString()})`; + this._noteString = `(${tr.getDisplayFret(n.tieOrigin!).toString()})`; } else { this._noteString = ''; } if (n.isTrill) { - this._trillNoteString = `(${(n.trillFret - n.beat.voice.bar.staff.transpositionPitch).toString()})`; - } else if (!ModelUtils.isAlmostEqualTo(n.harmonicValue, 0)) { - switch (n.harmonicType) { + this._trillNoteString = `(${tr.getDisplayTrillFret(n).toString()})`; + } else if (!ModelUtils.isAlmostEqualTo(harmonicValue, 0)) { + switch (harmonicType) { case HarmonicType.Artificial: case HarmonicType.Pinch: case HarmonicType.Tap: case HarmonicType.Semi: case HarmonicType.Feedback: - let s: string = (fret + n.harmonicValue).toString(); + let s: string = (fret + harmonicValue).toString(); // only first decimal char const i: number = s.indexOf(String.fromCharCode(46)); if (i >= 0) { @@ -141,7 +157,7 @@ export class NoteNumberGlyph extends Glyph { this.paintTrill(x, y, canvas); - const previousColor = ElementStyleHelper.applyNote(canvas, NoteSubElement.GuitarTabFretNumber, this._note); + const previousColor = this._applyColor(canvas); try { canvas.fillText(this._noteString!, x, y); } finally { @@ -155,7 +171,7 @@ export class NoteNumberGlyph extends Glyph { if (!this._trillNoteString) { return; } - const previousColor = ElementStyleHelper.applyNote(canvas, NoteSubElement.GuitarTabFretNumber, this._note); + const previousColor = this._applyColor(canvas); try { const prevFont: Font = this.renderer.scoreRenderer.canvas!.font; this.renderer.scoreRenderer.canvas!.font = this.renderer.resources.graceFont; @@ -166,6 +182,17 @@ export class NoteNumberGlyph extends Glyph { } } + private _applyColor(canvas: ICanvas): Color | undefined { + return this._isUnplayable + ? ElementStyleHelper.applyNoteWithDefault( + canvas, + NoteSubElement.GuitarTabFretNumber, + this._note, + this.renderer.resources.tabUnplayableFretColor + ) + : ElementStyleHelper.applyNote(canvas, NoteSubElement.GuitarTabFretNumber, this._note); + } + public buildBoundingsLookup(writer: IBoundsLookupWriter, cx: number, cy: number) { const scale = this.renderer.settings.display.scale; writer.addNote( diff --git a/packages/alphatab/src/rendering/glyphs/ScoreBeatGlyph.ts b/packages/alphatab/src/rendering/glyphs/ScoreBeatGlyph.ts index 6fdde8a926..5b958971b2 100644 --- a/packages/alphatab/src/rendering/glyphs/ScoreBeatGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/ScoreBeatGlyph.ts @@ -455,7 +455,7 @@ export class ScoreBeatGlyph extends BeatOnNoteGlyphBase { } else { container = aboveBeatEffects.get('StringNumber')! as StringNumberContainerGlyph; } - container.addString(n.string, n.realValue); + container.addString(n.string, n.realValue, n); } if (n.isPercussion) { const articulation = PercussionMapper.getArticulation(n); diff --git a/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts b/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts index 85d27f84dd..716610dd53 100644 --- a/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts @@ -2,6 +2,7 @@ import { EffectGlyph } from '@coderline/alphatab/rendering/glyphs/EffectGlyph'; import { MusicFontSymbol } from '@coderline/alphatab/model/MusicFontSymbol'; import { Note } from '@coderline/alphatab/model/Note'; import { CanvasHelper, type ICanvas } from '@coderline/alphatab/platform/ICanvas'; +import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; /** * @internal @@ -10,13 +11,15 @@ export class StringNumberContainerGlyph extends EffectGlyph { // top to bottom: highest note first private _strings: number[] = []; private _pitches: number[] = []; + private _notes: Note[] = []; - public addString(string: number, pitch: number) { + public addString(string: number, pitch: number, note: Note) { if (this._strings.indexOf(string) >= 0) { return; } this._strings.push(string); this._pitches.push(pitch); + this._notes.push(note); let i = this._strings.length - 1; while ( i > 0 && @@ -24,10 +27,12 @@ export class StringNumberContainerGlyph extends EffectGlyph { ) { this._strings[i] = this._strings[i - 1]; this._pitches[i] = this._pitches[i - 1]; + this._notes[i] = this._notes[i - 1]; i--; } this._strings[i] = string; this._pitches[i] = pitch; + this._notes[i] = note; } public override doLayout(): void { @@ -43,8 +48,9 @@ export class StringNumberContainerGlyph extends EffectGlyph { let y = 0; const circleHeight = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.GuitarString0)! * this.renderer.smuflMetrics.tuningGlyphCircleNumberScale; - for (const s of this._strings) { - const stringValue = stringCount - s; + for (const note of this._notes) { + // resolved on paint: the tab of the bar is laid out after this staff + const stringValue = stringCount - TabBarRenderer.resolveDisplayString(this.renderer, note); const symbol = ((MusicFontSymbol.GuitarString1 as number) + stringValue) as MusicFontSymbol; CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x, diff --git a/packages/alphatab/src/rendering/glyphs/TabBeatContainerGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabBeatContainerGlyph.ts index 204886c698..949a82bf2d 100644 --- a/packages/alphatab/src/rendering/glyphs/TabBeatContainerGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabBeatContainerGlyph.ts @@ -62,12 +62,12 @@ export class TabBeatContainerGlyph extends BeatContainerGlyph { // effect slurs: one arc per side of the beat (see TabSlurGlyph) // start effect slur on first beat if (n.isEffectSlurOrigin && n.effectSlurDestination) { - const direction = TabTieGlyph.getBeamDirectionForNote(n); + const direction = TabTieGlyph.getBeamDirectionForString(renderer.getDisplayString(n)); let slurStarts = this._effectSlurStarts; const group = slurStarts !== null && slurStarts.has(direction) ? null - : TabSlurGlyph.getEffectSlurGroup(this.beat, direction); + : TabSlurGlyph.getEffectSlurGroup(renderer, this.beat, direction); if (group) { if (!slurStarts) { slurStarts = new Set(); @@ -81,12 +81,12 @@ export class TabBeatContainerGlyph extends BeatContainerGlyph { } // end effect slur on last beat if (n.isEffectSlurDestination && n.effectSlurOrigin) { - const direction = TabTieGlyph.getBeamDirectionForNote(n.effectSlurOrigin); + const direction = TabTieGlyph.getBeamDirectionForString(renderer.getDisplayString(n.effectSlurOrigin)); let slurEnds = this._effectSlurEnds; const group = slurEnds !== null && slurEnds.has(direction) ? null - : TabSlurGlyph.getEffectSlurGroup(n.effectSlurOrigin.beat, direction); + : TabSlurGlyph.getEffectSlurGroup(renderer, n.effectSlurOrigin.beat, direction); if (group && group.endNote === n) { if (!slurEnds) { slurEnds = new Set(); diff --git a/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts index 646c7ec19d..a7211aac5b 100644 --- a/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts @@ -232,12 +232,12 @@ export class TabBeatGlyph extends BeatOnNoteGlyphBase { private _createNoteGlyph(n: Note): void { const tr: TabBarRenderer = this.renderer as TabBarRenderer; - const noteNumberGlyph: NoteNumberGlyph = new NoteNumberGlyph(0, 0, n); + const noteNumberGlyph: NoteNumberGlyph = new NoteNumberGlyph(0, 0, n, tr.getDisplayString(n)); const l: number = tr.getNoteLine(n); noteNumberGlyph.y = tr.getLineY(l); noteNumberGlyph.renderer = this.renderer; noteNumberGlyph.doLayout(); - this.noteNumbers!.addNoteGlyph(noteNumberGlyph, n); + this.noteNumbers!.addNoteGlyph(noteNumberGlyph); if (tr.drawsRhythm) { tr.collisionHelper.reserveBeatSlot( this.container.beat, diff --git a/packages/alphatab/src/rendering/glyphs/TabBendGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabBendGlyph.ts index bc4526ba68..45357f691f 100644 --- a/packages/alphatab/src/rendering/glyphs/TabBendGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabBendGlyph.ts @@ -200,9 +200,10 @@ export class TabBendGlyph extends Glyph implements ITieGlyph { } } this.width = 0; + const tabRenderer = this.renderer as TabBarRenderer; this._notes.sort((a, b) => { if (a.isStringed) { - return a.string - b.string; + return tabRenderer.getDisplayString(a) - tabRenderer.getDisplayString(b); } return a.realValue - b.realValue; }); @@ -691,7 +692,9 @@ export class TabBendGlyph extends Glyph implements ITieGlyph { if (firstPt.value === 0) { y1 = cy + smufl.tabBendStaffPadding; if (secondPt.offset === firstPt.offset) { - y1 += noteRenderer.getNoteY(note.beat.maxStringNote!, NoteYPosition.Top) - noteNumberAndLinePaddingY; + y1 += + noteRenderer.getNoteY(noteRenderer.getDisplayMaxStringNote(note.beat)!, NoteYPosition.Top) - + noteNumberAndLinePaddingY; } else { y1 += noteRenderer.getNoteY(note, NoteYPosition.Center); } @@ -702,7 +705,10 @@ export class TabBendGlyph extends Glyph implements ITieGlyph { const x2 = cx + dX * secondPt.offset; let y2: number; if (secondPt.lineValue === 0) { - y2 = cy + smufl.tabBendStaffPadding + noteRenderer.getNoteY(note.beat.maxStringNote!, NoteYPosition.Center); + y2 = + cy + + smufl.tabBendStaffPadding + + noteRenderer.getNoteY(noteRenderer.getDisplayMaxStringNote(note.beat)!, NoteYPosition.Center); } else { y2 = cy - smufl.tabBendPerValueHeight * secondPt.lineValue; } diff --git a/packages/alphatab/src/rendering/glyphs/TabBrushGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabBrushGlyph.ts index 060d489137..8d2d911d4b 100644 --- a/packages/alphatab/src/rendering/glyphs/TabBrushGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabBrushGlyph.ts @@ -37,8 +37,12 @@ export class TabBrushGlyph extends Glyph { public override paint(cx: number, cy: number, canvas: ICanvas): void { const tabBarRenderer: TabBarRenderer = this.renderer as TabBarRenderer; - const startY: number = cy + this.x + tabBarRenderer.getNoteY(this._beat.maxStringNote!, NoteYPosition.Top); - const endY: number = cy + this.y + tabBarRenderer.getNoteY(this._beat.minStringNote!, NoteYPosition.Bottom); + const startY: number = + cy + this.x + tabBarRenderer.getNoteY(tabBarRenderer.getDisplayMaxStringNote(this._beat)!, NoteYPosition.Top); + const endY: number = + cy + + this.y + + tabBarRenderer.getNoteY(tabBarRenderer.getDisplayMinStringNote(this._beat)!, NoteYPosition.Bottom); const arrowX: number = cx + this.x + this.width / 2; const arrowSize = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.ArrowheadBlackDown)!; if (this._beat.brushType !== BrushType.None) { diff --git a/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts index c71ca1ad82..ccd6b22e58 100644 --- a/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts @@ -7,6 +7,7 @@ import { NoteXPosition, NoteYPosition } from '@coderline/alphatab/rendering/BarR import { DeadSlappedBeatGlyph } from '@coderline/alphatab/rendering/glyphs/DeadSlappedBeatGlyph'; import { Glyph } from '@coderline/alphatab/rendering/glyphs/Glyph'; import type { NoteNumberGlyph } from '@coderline/alphatab/rendering/glyphs/NoteNumberGlyph'; +import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { ElementStyleHelper } from '@coderline/alphatab/rendering/utils/ElementStyleHelper'; /** @@ -20,6 +21,8 @@ export class TabNoteChordGlyph extends Glyph { public beat!: Beat; public maxStringNote: Note | null = null; public minStringNote: Note | null = null; + private _maxString: number = 0; + private _minString: number = 0; private _beatEffects: Map | null = null; public noteStringWidth: number = 0; @@ -36,13 +39,26 @@ export class TabNoteChordGlyph extends Glyph { public getNoteGlyphForString(str: number): NoteNumberGlyph | null { const notes = this._notes; for (let i = notes.length - 1; i >= 0; i--) { - if (notes[i].note.string === str) { + if (notes[i].displayString === str) { return notes[i]; } } return null; } + /** + * The glyph of the given note, or the glyph shown on its string if the note has none (e.g. a hidden note). + */ + public getNoteGlyph(note: Note): NoteNumberGlyph | null { + const notes = this._notes; + for (let i = notes.length - 1; i >= 0; i--) { + if (notes[i].note === note) { + return notes[i]; + } + } + return this.getNoteGlyphForString((this.renderer as TabBarRenderer).getDisplayString(note)); + } + public get beatEffects(): Map { let effects = this._beatEffects; if (!effects) { @@ -64,7 +80,7 @@ export class TabNoteChordGlyph extends Glyph { } public getNoteX(note: Note, requestedPosition: NoteXPosition): number { - const n = this.getNoteGlyphForString(note.string); + const n = this.getNoteGlyph(note); if (n) { let pos = this.x + n.x; switch (requestedPosition) { @@ -92,7 +108,7 @@ export class TabNoteChordGlyph extends Glyph { } public getNoteY(note: Note, requestedPosition: NoteYPosition): number { - const n = this.getNoteGlyphForString(note.string); + const n = this.getNoteGlyph(note); if (n) { let pos = this.y + n.y; @@ -176,17 +192,20 @@ export class TabNoteChordGlyph extends Glyph { /** * Adds a note number that is already laid out. */ - public addNoteGlyph(noteGlyph: NoteNumberGlyph, note: Note): void { + public addNoteGlyph(noteGlyph: NoteNumberGlyph): void { if (this._notes.length === 0) { this._notes = [noteGlyph]; } else { this._notes.push(noteGlyph); } - if (!this.minStringNote || note.string < this.minStringNote.string) { - this.minStringNote = note; + const str = noteGlyph.displayString; + if (!this.minStringNote || str < this._minString) { + this.minStringNote = noteGlyph.note; + this._minString = str; } - if (!this.maxStringNote || note.string > this.maxStringNote.string) { - this.maxStringNote = note; + if (!this.maxStringNote || str > this._maxString) { + this.maxStringNote = noteGlyph.note; + this._maxString = str; } } diff --git a/packages/alphatab/src/rendering/glyphs/TabSlurGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabSlurGlyph.ts index e5efe08523..a6c2e94304 100644 --- a/packages/alphatab/src/rendering/glyphs/TabSlurGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabSlurGlyph.ts @@ -1,6 +1,7 @@ import type { Beat } from '@coderline/alphatab/model/Beat'; import type { Note } from '@coderline/alphatab/model/Note'; import { TabTieGlyph } from '@coderline/alphatab/rendering/glyphs/TabTieGlyph'; +import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { BeamDirection } from '@coderline/alphatab/rendering/utils/BeamDirection'; /** @@ -25,7 +26,11 @@ export class TabSlurGlyph extends TabTieGlyph { * Gets the notes the effect slur arc on the given side of the beat connects. * @returns The notes, or null if no effect slur chain starts on this side of the beat. */ - public static getEffectSlurGroup(beat: Beat, direction: BeamDirection): TabEffectSlurGroup | null { + public static getEffectSlurGroup( + renderer: TabBarRenderer, + beat: Beat, + direction: BeamDirection + ): TabEffectSlurGroup | null { const isUp = direction === BeamDirection.Up; let startNote: Note | null = null; let endNote: Note | null = null; @@ -35,7 +40,7 @@ export class TabSlurGlyph extends TabTieGlyph { !n.isVisible || !n.isEffectSlurOrigin || !destination || - TabTieGlyph.getBeamDirectionForNote(n) !== direction + TabTieGlyph.getBeamDirectionForString(renderer.getDisplayString(n)) !== direction ) { continue; } diff --git a/packages/alphatab/src/rendering/glyphs/TabTieGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabTieGlyph.ts index 7b4d0192bc..e2fc3019ee 100644 --- a/packages/alphatab/src/rendering/glyphs/TabTieGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabTieGlyph.ts @@ -1,5 +1,6 @@ import type { Note } from '@coderline/alphatab/model/Note'; import { NoteTieGlyph } from '@coderline/alphatab/rendering/glyphs/TieGlyph'; +import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { BeamDirection } from '@coderline/alphatab/rendering/utils/BeamDirection'; /** @@ -10,13 +11,22 @@ export class TabTieGlyph extends NoteTieGlyph { if (this.isLeftHandTap) { return BeamDirection.Up; } - return TabTieGlyph.getBeamDirectionForNote(this.startNote); + return TabTieGlyph.getBeamDirectionForString( + (this.renderer as TabBarRenderer).getDisplayString(this.startNote) + ); } /** - * The side of tab ties and slurs: above the upper three strings, below the lower ones. + * The side of ties and slurs of the note on its model string. */ public static getBeamDirectionForNote(note: Note): BeamDirection { - return note.string > 3 ? BeamDirection.Up : BeamDirection.Down; + return TabTieGlyph.getBeamDirectionForString(note.string); + } + + /** + * The side of tab ties and slurs: above the upper three strings, below the lower ones. + */ + public static getBeamDirectionForString(str: number): BeamDirection { + return str > 3 ? BeamDirection.Up : BeamDirection.Down; } } diff --git a/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts b/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts index dfef8789e9..d8928824e7 100644 --- a/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts +++ b/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts @@ -10,6 +10,7 @@ import { ScoreLayout } from '@coderline/alphatab/rendering/layout/ScoreLayout'; import { RenderFinishedEventArgs } from '@coderline/alphatab/rendering/RenderFinishedEventArgs'; import type { MasterBarsRenderers } from '@coderline/alphatab/rendering/staves/MasterBarsRenderers'; import type { StaffSystem } from '@coderline/alphatab/rendering/staves/StaffSystem'; +import { TabFingeringSolver } from '@coderline/alphatab/rendering/utils/TabFingeringSolver'; /** * How the fill loop chose the bars of a pooled system: the system holds the measured master bars @@ -117,7 +118,11 @@ export abstract class VerticalLayoutBase extends ScoreLayout { public override doUpdateForBars(renderHints: RenderHints): boolean { this._reuseViewPort = renderHints.reuseViewport ?? false; - const firstModifiedMasterBar = renderHints.firstChangedMasterBar!; + // a transposed tab is fingered per segment of linked bars which has to be laid out as a whole + const firstModifiedMasterBar = TabFingeringSolver.firstAffectedBarIndex( + this.renderer.tracks!, + renderHints.firstChangedMasterBar! + ); // first update existing systems as needed const systemIndex = this._systems.findIndex(s => { diff --git a/packages/alphatab/src/rendering/utils/ElementStyleHelper.ts b/packages/alphatab/src/rendering/utils/ElementStyleHelper.ts index dd3d05b9c6..57ef4cc05a 100644 --- a/packages/alphatab/src/rendering/utils/ElementStyleHelper.ts +++ b/packages/alphatab/src/rendering/utils/ElementStyleHelper.ts @@ -313,6 +313,19 @@ export class ElementStyleHelper { return ElementStyleHelper._apply(canvas, element, note.style, defaultColor, forceDefault); } + /** + * Applies the color of the given note element like {@link applyNote}, using the given color + * when the note style does not define the element. + */ + public static applyNoteWithDefault( + canvas: ICanvas, + element: NoteSubElement, + note: Note, + defaultColor: Color + ): Color | undefined { + return ElementStyleHelper._apply(canvas, element, note.style, defaultColor, true); + } + /** * Restores the canvas color changed by one of the `apply*` methods. * @param previousColor The value returned by the `apply*` method. diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts index 353f100f13..71635577cb 100644 --- a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts +++ b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts @@ -6,6 +6,7 @@ import type { Note } from '@coderline/alphatab/model/Note'; import { SlideInType } from '@coderline/alphatab/model/SlideInType'; import { SlideOutType } from '@coderline/alphatab/model/SlideOutType'; import type { Staff } from '@coderline/alphatab/model/Staff'; +import type { Track } from '@coderline/alphatab/model/Track'; import { VibratoType } from '@coderline/alphatab/model/VibratoType'; import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; @@ -141,6 +142,21 @@ export class TabFingeringSolver { return b; } + /** + * The first bar whose tab fingering may change when the given bar changes, considering the transposed tabs of all tracks. + */ + public static firstAffectedBarIndex(tracks: Track[], barIndex: number): number { + let first = barIndex; + for (const track of tracks) { + for (const staff of track.staves) { + if (staff.showTablature && TabFingeringSolver.isActive(staff) && barIndex < staff.bars.length) { + first = Math.min(first, TabFingeringSolver.segmentStart(staff, barIndex)); + } + } + } + return first; + } + /** * The last bar of the segment starting at the given bar. */ @@ -568,7 +584,11 @@ export class TabFingeringRun { while (insertAt > optionStart) { const previousDelta = options[insertAt - 1]; const previousFret = optionFret[insertAt - 1]; - if (previousDelta === 0 || previousFret < headFret || (previousFret === headFret && previousDelta < delta)) { + if ( + previousDelta === 0 || + previousFret < headFret || + (previousFret === headFret && previousDelta < delta) + ) { break; } insertAt--; @@ -782,7 +802,8 @@ export class TabFingeringRun { let sequence = 0; const previousStart = t === 0 ? -1 : stateBase[t - 1]; const previousCount = t === 0 ? 1 : stateCount[t - 1]; - const gapQuarters = t === 0 ? 0 : (this._sliceTick[t] - this._sliceTick[t - 1]) / TabFingeringRun._ticksPerQuarter; + const gapQuarters = + t === 0 ? 0 : (this._sliceTick[t] - this._sliceTick[t - 1]) / TabFingeringRun._ticksPerQuarter; for (let p = 0; p < previousCount; p++) { const previousState = previousStart + p; @@ -829,7 +850,10 @@ export class TabFingeringRun { let same = true; for (let a = activeStart; a < activeEnd && same; a++) { const g = this._activeGroups[a]; - if (this._groupLast[g] > t && cDeltas[c * activeLength + (a - activeStart)] !== groupDelta[g]) { + if ( + this._groupLast[g] > t && + cDeltas[c * activeLength + (a - activeStart)] !== groupDelta[g] + ) { same = false; } } @@ -840,7 +864,16 @@ export class TabFingeringRun { let write = -1; if (slot >= 0) { - if (TabFingeringRun._isBetter(unplayable, moved, rest, cUnplayable[slot], cMoved[slot], cRest[slot])) { + if ( + TabFingeringRun._isBetter( + unplayable, + moved, + rest, + cUnplayable[slot], + cMoved[slot], + cRest[slot] + ) + ) { write = slot; } } else if (candidateCount < beamWidth) { @@ -882,7 +915,16 @@ export class TabFingeringRun { worst = c; } } - if (TabFingeringRun._isBetter(unplayable, moved, rest, cUnplayable[worst], cMoved[worst], cRest[worst])) { + if ( + TabFingeringRun._isBetter( + unplayable, + moved, + rest, + cUnplayable[worst], + cMoved[worst], + cRest[worst] + ) + ) { write = worst; } } @@ -929,8 +971,22 @@ export class TabFingeringRun { } if ( best < 0 || - TabFingeringRun._isBetter(cUnplayable[c], cMoved[c], cRest[c], cUnplayable[best], cMoved[best], cRest[best]) || - (TabFingeringRun._isEqual(cUnplayable[c], cMoved[c], cRest[c], cUnplayable[best], cMoved[best], cRest[best]) && + TabFingeringRun._isBetter( + cUnplayable[c], + cMoved[c], + cRest[c], + cUnplayable[best], + cMoved[best], + cRest[best] + ) || + (TabFingeringRun._isEqual( + cUnplayable[c], + cMoved[c], + cRest[c], + cUnplayable[best], + cMoved[best], + cRest[best] + ) && cSequence[c] < cSequence[best]) ) { best = c; diff --git a/packages/alphatab/test/generated/SerializerFill.ts b/packages/alphatab/test/generated/SerializerFill.ts index 003dd8eaf2..d27a047683 100644 --- a/packages/alphatab/test/generated/SerializerFill.ts +++ b/packages/alphatab/test/generated/SerializerFill.ts @@ -566,6 +566,9 @@ export class SerializerFill { { obj.scoreInfoColor = new Color(1, 2, 3, 4); } + { + obj.tabUnplayableFretColor = new Color(1, 2, 3, 4); + } } public static fillSettings(obj: Settings, depth: number = 0): void { if (depth > 8) { diff --git a/packages/alphatab/test/rendering/TabFingeringPartialUpdate.test.ts b/packages/alphatab/test/rendering/TabFingeringPartialUpdate.test.ts new file mode 100644 index 0000000000..69e4eb0451 --- /dev/null +++ b/packages/alphatab/test/rendering/TabFingeringPartialUpdate.test.ts @@ -0,0 +1,88 @@ +/** + * A transposed tab is fingered per segment of linked bars. A partial render starting inside a + * segment which began in an earlier system must re-finger the whole segment like a fresh render. + */ +import { ScoreLoader } from '@coderline/alphatab/importer/ScoreLoader'; +import type { Note } from '@coderline/alphatab/model/Note'; +import type { Score } from '@coderline/alphatab/model/Score'; +import type { RenderHints } from '@coderline/alphatab/rendering/IScoreRenderer'; +import { ScoreRenderer } from '@coderline/alphatab/rendering/ScoreRenderer'; +import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; +import { Settings } from '@coderline/alphatab/Settings'; +import { StaveProfile } from '@coderline/alphatab/StaveProfile'; +import { describe, expect, it } from 'vitest'; + +/** + * @internal + */ +class TabFingeringRenderHints implements RenderHints { + public reuseViewport?: boolean; + public firstChangedMasterBar?: number; +} + +describe('TabFingeringPartialUpdate', () => { + /** + * @static + */ + function createSettings(): Settings { + const settings = new Settings(); + settings.core.engine = 'svg'; + settings.core.enableLazyLoading = true; + settings.display.staveProfile = StaveProfile.Tab; + settings.display.barsPerRow = 2; + return settings; + } + + /** + * @static + */ + function createScore(settings: Settings): Score { + // the hammer-on crosses from the first into the second system + return ScoreLoader.loadAlphaTex( + '\\transpose -4 :4 5.3 5.3 5.3 5.3 | 5.3 5.3 5.3 2.3{h} | 4.3 5.3 5.3 5.3 | 5.3 5.3 5.3 5.3', + settings + ); + } + + /** + * @static + */ + function render(settings: Settings, score: Score): ScoreRenderer { + const renderer = new ScoreRenderer(settings); + renderer.width = 1000; + renderer.renderScore(score, [0]); + return renderer; + } + + /** + * @static + */ + function displayString(renderer: ScoreRenderer, note: Note): number { + const tab = renderer.layout!.getRendererForBar(TabBarRenderer.StaffId, note.beat.voice.bar) as TabBarRenderer; + return tab.getDisplayString(note); + } + + it('re-fingers the segment started in an earlier system', () => { + const settings = createSettings(); + const score = createScore(settings); + const staff = score.tracks[0].staves[0]; + const origin = staff.bars[1].voices[0].beats[3].notes[0]; + const destination = staff.bars[2].voices[0].beats[0].notes[0]; + + const renderer = render(settings, score); + // moved to the D string together with its destination + expect(displayString(renderer, origin)).toBe(3); + expect(displayString(renderer, destination)).toBe(3); + + // the destination does not fit on the D string anymore, the pair stays on the G string + destination.fret = 24; + const hints = new TabFingeringRenderHints(); + hints.firstChangedMasterBar = 2; + renderer.render(hints); + + const fresh = render(settings, score); + expect(displayString(fresh, origin)).toBe(4); + expect(displayString(renderer, origin)).toBe(displayString(fresh, origin)); + expect(displayString(renderer, destination)).toBe(displayString(fresh, destination)); + }); +}); diff --git a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts index b922030819..2b73c04565 100644 --- a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts +++ b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts @@ -130,9 +130,7 @@ describe('TabFingeringSolverTest', () => { }); it('moves hammer-ons and slides as a whole', () => { - expect(display(staffOf('\\transpose -4 2.3{h} 4.3 2.3{ss} 4.3'))).toEqual([ - ['3.4*', '5.4*', '3.4*', '5.4*'] - ]); + expect(display(staffOf('\\transpose -4 2.3{h} 4.3 2.3{ss} 4.3'))).toEqual([['3.4*', '5.4*', '3.4*', '5.4*']]); }); it('allows pull-offs to open strings', () => { From 83a59113b75c32d31d044c2b0046a9ac983fc980 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:30:21 +0100 Subject: [PATCH 05/12] test(rendering): add visual tests for transposed tabs --- .../guitar-tabs/transpose-down.png | Bin 0 -> 26391 bytes .../visual-tests/guitar-tabs/transpose-up.png | Bin 0 -> 8174 bytes .../visualTests/features/GuitarTabs.test.ts | 30 ++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-down.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-up.png diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-down.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-down.png new file mode 100644 index 0000000000000000000000000000000000000000..4060d6e9b9522d987b80175ca35aed33c7b5eccd GIT binary patch literal 26391 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 { 'test-data/visual-tests/guitar-tabs/multi-voice-same-string.png' ); }); + + it('transpose-down', async () => { + // open strings, chords, ties across bars, legato, bends, harmonics, trills and dead notes + // which do not fit on their string after transposing down + const settings = new Settings(); + settings.notation.transpositionPitches = [-4]; + await VisualTestHelper.runVisualTestTex( + ` + \\track \\staff { score tabs } + :4 0.6 3.5{string} 2.4 0.3 | (0.1 0.2 0.3) 3.5 3.5 3.5 | 3.5{t} 2.3{h} 4.3 4.3{b (0 4)} | + 12.6{nh} 12.5{nh} 5.3{tr 7 16} 0.6{x} + `, + 'test-data/visual-tests/guitar-tabs/transpose-down.png', + settings + ); + }); + + it('transpose-up', async () => { + // frets beyond the neck after transposing up + const settings = new Settings(); + settings.display.staveProfile = StaveProfile.Tab; + settings.notation.transpositionPitches = [7]; + await VisualTestHelper.runVisualTestTex( + ` + :4 17.1 20.1 (19.2 20.1) 22.2 | 5.6 7.5 0.1 3.3 + `, + 'test-data/visual-tests/guitar-tabs/transpose-up.png', + settings + ); + }); }); From 63bf95073de1f76ba87713cb3353589ffa646be5 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:42:21 +0100 Subject: [PATCH 06/12] perf(rendering): allocate nothing for unchanged tab segments, bound the search buffers The fast path of TabFingeringSolver reads the model directly instead of building the note tables first, so segments keeping their fingering allocate nothing. The beam search keeps only the states of the previous slice plus back pointers and new-group deltas in typed arrays, merges the voices instead of sorting beats and avoids splice and iterator allocations in its loops. Natural harmonics needing the artificial-harmonic fallback on their own string no longer pass the fast path, which displayed them at the wrong pitch. --- .../src/rendering/utils/TabFingeringSolver.ts | 516 ++++++++++-------- .../test/rendering/TabFingeringSolver.test.ts | 4 + 2 files changed, 307 insertions(+), 213 deletions(-) diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts index 71635577cb..95eb432a9b 100644 --- a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts +++ b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts @@ -115,9 +115,12 @@ export class TabFingeringSolver { public static isSegmentStart(staff: Staff, barIndex: number): boolean { const firstChecked = Math.max(0, barIndex - TabFingeringSolver._maxLinkBarDistance); for (let b = barIndex - 1; b >= firstChecked; b--) { - for (const voice of staff.bars[b].voices) { - for (const beat of voice.beats) { - for (const note of beat.notes) { + for (let v = 0; v < staff.bars[b].voices.length; v++) { + const voice = staff.bars[b].voices[v]; + for (let k = 0; k < voice.beats.length; k++) { + const beat = voice.beats[k]; + for (let n = 0; n < beat.notes.length; n++) { + const note = beat.notes[n]; for (let kind = 0; kind < 3; kind++) { const target = TabFingeringSolver.nextLinked(note, kind); if (target !== null && target.beat.voice.bar.index >= barIndex) { @@ -164,9 +167,12 @@ export class TabFingeringSolver { let last = firstBarIndex; let scanned = firstBarIndex; while (scanned <= last && scanned < staff.bars.length) { - for (const voice of staff.bars[scanned].voices) { - for (const beat of voice.beats) { - for (const note of beat.notes) { + for (let v = 0; v < staff.bars[scanned].voices.length; v++) { + const voice = staff.bars[scanned].voices[v]; + for (let k = 0; k < voice.beats.length; k++) { + const beat = voice.beats[k]; + for (let n = 0; n < beat.notes.length; n++) { + const note = beat.notes[n]; for (let kind = 0; kind < 3; kind++) { const target = TabFingeringSolver.nextLinked(note, kind); if (target !== null && target.beat.voice.bar.index > last) { @@ -300,10 +306,10 @@ export class TabFingeringRun { } public solve(): TabFingeringSegment | null { - this._collectNotes(); if (this._isIdentity()) { return null; } + this._collectNotes(); this._buildGroups(); this._buildSlices(); @@ -342,7 +348,8 @@ export class TabFingeringRun { let voiceCount = 0; let beatCount = 0; for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { - for (const voice of bars[b].voices) { + for (let v = 0; v < bars[b].voices.length; v++) { + const voice = bars[b].voices[v]; voiceCount++; beatCount += voice.beats.length; } @@ -357,13 +364,16 @@ export class TabFingeringRun { let beatIndex = 0; for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { this._barVoiceBase[b - this._firstBarIndex] = voiceIndex; - for (const voice of bars[b].voices) { + for (let v = 0; v < bars[b].voices.length; v++) { + const voice = bars[b].voices[v]; this._voiceBeatBase[voiceIndex] = beatIndex; voiceIndex++; - for (const beat of voice.beats) { + for (let k = 0; k < voice.beats.length; k++) { + const beat = voice.beats[k]; this._beatNoteBase[beatIndex] = notes.length; beatIndex++; - for (const note of beat.notes) { + for (let n = 0; n < beat.notes.length; n++) { + const note = beat.notes[n]; notes.push(note); } } @@ -467,26 +477,61 @@ export class TabFingeringRun { const fret = target - stringPitch; this._evalFret = fret; - if (fret < 0 || fret > maxFret) { - return false; - } - if (fret === 0 && this._noOpen[i] !== 0) { - return false; - } const trill = this._trill[i]; - if (trill >= 0) { - const trillFret = trill - stringPitch; - if (trillFret < 0 || trillFret > maxFret) { - return false; - } + return TabFingeringRun._isPlayableFret(fret, maxFret, this._noOpen[i] !== 0, trill >= 0, trill - stringPitch); + } + + private static _isPlayableFret( + fret: number, + maxFret: number, + needsFrettedString: boolean, + hasTrill: boolean, + trillFret: number + ): boolean { + if (fret < 0 || fret > maxFret || (fret === 0 && needsFrettedString)) { + return false; } - return true; + return !hasTrill || (trillFret >= 0 && trillFret <= maxFret); } + /** + * Whether every note is playable on its model string with the fret shifted by the transposition, + * natural harmonics on a node of their string. Reads the model directly to allocate nothing for + * the common case. + */ private _isIdentity(): boolean { - for (let i = 0; i < this._notes.length; i++) { - if (this._kind[i] !== TabFingeringRun._kindSkip && !this._evaluate(i, this._originalString[i])) { - return false; + const staff = this._staff; + const transpositionPitch = staff.transpositionPitch; + for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { + for (let v = 0; v < staff.bars[b].voices.length; v++) { + const voice = staff.bars[b].voices[v]; + for (let k = 0; k < voice.beats.length; k++) { + const beat = voice.beats[k]; + for (let n = 0; n < beat.notes.length; n++) { + const note = beat.notes[n]; + if (!note.isStringed || note.string < 1 || note.string > this._stringCount || note.isDead) { + continue; + } + if (TabFingeringSolver.isNaturalHarmonic(note)) { + if (TabFingeringSolver.findNaturalNodeOnModelString(note) < 0) { + return false; + } + continue; + } + const maxFret = Math.max(this._options.defaultMaxFret - this._capo, note.fret); + if ( + !TabFingeringRun._isPlayableFret( + note.fret - transpositionPitch, + maxFret, + TabFingeringRun._needsFrettedString(note), + note.isTrill, + note.isTrill ? note.trillFret - transpositionPitch : 0 + ) + ) { + return false; + } + } + } } } return true; @@ -594,8 +639,14 @@ export class TabFingeringRun { insertAt--; } } - options.splice(insertAt, 0, delta); - optionFret.splice(insertAt, 0, headFret); + options.push(delta); + optionFret.push(headFret); + for (let m = options.length - 1; m > insertAt; m--) { + options[m] = options[m - 1]; + optionFret[m] = optionFret[m - 1]; + } + options[insertAt] = delta; + optionFret[insertAt] = headFret; } if (!hasZero) { // last resort: keep the model strings, unplayable notes are flagged @@ -606,6 +657,16 @@ export class TabFingeringRun { this._groupOptionBase.push(options.length); } + private _hasSolvedNotes(beat: Beat): boolean { + const notes = beat.notes; + for (let n = 0; n < notes.length; n++) { + if (this._kind[this._indexOf(notes[n])] !== TabFingeringRun._kindSkip) { + return true; + } + } + return false; + } + private static _graceRank(beat: Beat): number { return beat.graceType === GraceType.None ? TabFingeringRun._graceRankMain : beat.graceIndex; } @@ -630,51 +691,69 @@ export class TabFingeringRun { private _buildSlices(): void { const bars = this._staff.bars; - const beats: Beat[] = []; - for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { - for (const voice of bars[b].voices) { - for (const beat of voice.beats) { - for (const note of beat.notes) { - const i = this._indexOf(note); - if (this._kind[i] !== TabFingeringRun._kindSkip) { - beats.push(beat); - break; - } - } - } - } - } - beats.sort((a, b) => TabFingeringRun._compareBeats(a, b)); - const endTick: number[] = []; const sliceTick = this._sliceTick; let previous: Beat | null = null; - for (const beat of beats) { - if ( - previous === null || - previous.voice.bar.index !== beat.voice.bar.index || - previous.displayStart !== beat.displayStart || - TabFingeringRun._graceRank(previous) !== TabFingeringRun._graceRank(beat) - ) { - this._sliceNoteBase.push(this._sliceNotes.length); - sliceTick.push(beat.absoluteDisplayStart); + let voicePosition = new Int32Array(4); + for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { + const voices = bars[b].voices; + if (voicePosition.length < voices.length) { + voicePosition = new Int32Array(voices.length); } - previous = beat; - const slice = sliceTick.length - 1; - for (const note of beat.notes) { - const i = this._indexOf(note); - if (this._kind[i] === TabFingeringRun._kindSkip) { - continue; + voicePosition.fill(0); + // merge the voices, each of them is in slice order already + while (true) { + let beat: Beat | null = null; + let beatVoice = -1; + for (let v = 0; v < voices.length; v++) { + const voiceBeats = voices[v].beats; + while ( + voicePosition[v] < voiceBeats.length && + !this._hasSolvedNotes(voiceBeats[voicePosition[v]]) + ) { + voicePosition[v]++; + } + if (voicePosition[v] < voiceBeats.length) { + const candidate = voiceBeats[voicePosition[v]]; + if (beat === null || TabFingeringRun._compareBeats(candidate, beat) < 0) { + beat = candidate; + beatVoice = v; + } + } + } + if (beat === null) { + break; } - this._slice[i] = slice; - this._sliceNotes.push(i); - let end = beat.absoluteDisplayStart + beat.displayDuration; - const letRingDestination = note.isLetRing ? note.letRingDestination : null; - if (letRingDestination !== null) { - const destinationBeat = letRingDestination.beat; - end = Math.max(end, destinationBeat.absoluteDisplayStart + destinationBeat.displayDuration); + voicePosition[beatVoice]++; + + if ( + previous === null || + previous.voice.bar.index !== beat.voice.bar.index || + previous.displayStart !== beat.displayStart || + TabFingeringRun._graceRank(previous) !== TabFingeringRun._graceRank(beat) + ) { + this._sliceNoteBase.push(this._sliceNotes.length); + sliceTick.push(beat.absoluteDisplayStart); + } + previous = beat; + const slice = sliceTick.length - 1; + const notes = beat.notes; + for (let n = 0; n < notes.length; n++) { + const note = notes[n]; + const i = this._indexOf(note); + if (this._kind[i] === TabFingeringRun._kindSkip) { + continue; + } + this._slice[i] = slice; + this._sliceNotes.push(i); + let end = beat.absoluteDisplayStart + beat.displayDuration; + const letRingDestination = note.isLetRing ? note.letRingDestination : null; + if (letRingDestination !== null) { + const destinationBeat = letRingDestination.beat; + end = Math.max(end, destinationBeat.absoluteDisplayStart + destinationBeat.displayDuration); + } + endTick.push(end); } - endTick.push(end); } } this._sliceNoteBase.push(this._sliceNotes.length); @@ -707,9 +786,9 @@ export class TabFingeringRun { private _fillBuckets(counts: number[], base: number[]): void { let sum = 0; - for (const c of counts) { + for (let i = 0; i < counts.length; i++) { base.push(sum); - sum += c; + sum += counts[i]; } base.push(sum); } @@ -755,86 +834,112 @@ export class TabFingeringRun { /** * Beam search over the slices, each state holding the string delta of every group active in its slice. + * Only the states of the previous slice are kept, plus per slice the back pointers and the deltas of the + * groups starting there to follow the best path back. * @returns The string delta per group. */ - private _search(): number[] { + private _search(): Int32Array { const options = this._options; const beamWidth = options.beamWidth; const sliceCount = this._sliceTick.length; + const groupCount = this._groupCount; + const activeBase = this._activeBase; + const activeGroups = this._activeGroups; + const groupFirst = this._groupFirst; + const groupLast = this._groupLast; - // committed states of all slices - const stateBase: number[] = []; - const stateCount: number[] = []; - const stUnplayable: number[] = []; - const stMoved: number[] = []; - const stRest: number[] = []; - const stCenter: number[] = []; - const stBack: number[] = []; - const stDeltaBase: number[] = []; - const stDeltas: number[] = []; - - // candidates of the current slice - const cUnplayable: number[] = []; - const cMoved: number[] = []; - const cRest: number[] = []; - const cCenter: number[] = []; - const cBack: number[] = []; - const cSequence: number[] = []; - const cDeltas: number[] = []; - - const groupDelta: number[] = new Array(this._groupCount).fill(0); - const choice: number[] = []; - const newGroups: number[] = []; + let maxActive = 1; + for (let t = 0; t < sliceCount; t++) { + maxActive = Math.max(maxActive, activeBase[t + 1] - activeBase[t]); + } + // groups starting per slice, in the order of the active groups + const newGroupBase = new Int32Array(sliceCount + 1); + for (let g = 0; g < groupCount; g++) { + newGroupBase[groupFirst[g] + 1]++; + } for (let t = 0; t < sliceCount; t++) { - const activeStart = this._activeBase[t]; - const activeEnd = this._activeBase[t + 1]; - const activeLength = activeEnd - activeStart; - newGroups.splice(0, newGroups.length); - for (let a = activeStart; a < activeEnd; a++) { - const g = this._activeGroups[a]; - if (this._groupFirst[g] === t) { - newGroups.push(g); + newGroupBase[t + 1] += newGroupBase[t]; + } + const newGroupIds = new Int32Array(groupCount); + const newGroupPositions = new Int32Array(groupCount); + for (let t = 0; t < sliceCount; t++) { + let n = newGroupBase[t]; + for (let a = activeBase[t]; a < activeBase[t + 1]; a++) { + const g = activeGroups[a]; + if (groupFirst[g] === t) { + newGroupIds[n] = g; + newGroupPositions[n] = a - activeBase[t]; + n++; } } + } + + // the sorted states of the previous slice + const stateUnplayable = new Int32Array(beamWidth); + const stateMoved = new Int32Array(beamWidth); + const stateRest: number[] = new Array(beamWidth).fill(0); + const stateCenter: number[] = new Array(beamWidth).fill(0); + const stateDeltas = new Int8Array(beamWidth * maxActive); + let stateCount = 0; + + // the unsorted candidates of the current slice + const candidateUnplayable = new Int32Array(beamWidth); + const candidateMoved = new Int32Array(beamWidth); + const candidateRest: number[] = new Array(beamWidth).fill(0); + const candidateCenter: number[] = new Array(beamWidth).fill(0); + const candidateBack = new Int32Array(beamWidth); + const candidateSequence = new Int32Array(beamWidth); + const candidateDeltas = new Int8Array(beamWidth * maxActive); + const candidateCommitted = new Uint8Array(beamWidth); + + // kept for the path back + const back = new Int32Array(sliceCount * beamWidth); + const newDeltas = new Int8Array(groupCount * beamWidth); + + const groupDelta = new Int32Array(groupCount); + const choice = new Int32Array(maxActive); + + for (let t = 0; t < sliceCount; t++) { + const activeStart = activeBase[t]; + const activeEnd = activeBase[t + 1]; + const activeLength = activeEnd - activeStart; + const newStart = newGroupBase[t]; + const newCount = newGroupBase[t + 1] - newStart; let candidateCount = 0; let sequence = 0; - const previousStart = t === 0 ? -1 : stateBase[t - 1]; - const previousCount = t === 0 ? 1 : stateCount[t - 1]; + const previousCount = t === 0 ? 1 : stateCount; + const previousActiveStart = t === 0 ? 0 : activeBase[t - 1]; + const previousActiveLength = t === 0 ? 0 : activeStart - previousActiveStart; const gapQuarters = t === 0 ? 0 : (this._sliceTick[t] - this._sliceTick[t - 1]) / TabFingeringRun._ticksPerQuarter; for (let p = 0; p < previousCount; p++) { - const previousState = previousStart + p; let previousUnplayable = 0; let previousMoved = 0; let previousRest = 0; let previousCenter = -1; if (t > 0) { - previousUnplayable = stUnplayable[previousState]; - previousMoved = stMoved[previousState]; - previousRest = stRest[previousState]; - previousCenter = stCenter[previousState]; + previousUnplayable = stateUnplayable[p]; + previousMoved = stateMoved[p]; + previousRest = stateRest[p]; + previousCenter = stateCenter[p]; // groups continuing from the previous slice keep their delta - const previousActiveStart = this._activeBase[t - 1]; - const previousActiveEnd = this._activeBase[t]; - const deltaBase = stDeltaBase[previousState]; - for (let a = previousActiveStart; a < previousActiveEnd; a++) { - groupDelta[this._activeGroups[a]] = stDeltas[deltaBase + (a - previousActiveStart)]; + for (let a = 0; a < previousActiveLength; a++) { + groupDelta[activeGroups[previousActiveStart + a]] = stateDeltas[p * previousActiveLength + a]; } } - choice.splice(0, choice.length); - for (let k = 0; k < newGroups.length; k++) { - choice.push(0); + for (let k = 0; k < newCount; k++) { + choice[k] = 0; } let leaves = 0; let done = false; while (!done && leaves < options.maxLeavesPerState) { - for (let k = 0; k < newGroups.length; k++) { - const g = newGroups[k]; + for (let k = 0; k < newCount; k++) { + const g = newGroupIds[newStart + k]; groupDelta[g] = this._groupOptions[this._groupOptionBase[g] + choice[k]]; } leaves++; @@ -848,12 +953,9 @@ export class TabFingeringRun { let slot = -1; for (let c = 0; c < candidateCount && slot < 0; c++) { let same = true; - for (let a = activeStart; a < activeEnd && same; a++) { - const g = this._activeGroups[a]; - if ( - this._groupLast[g] > t && - cDeltas[c * activeLength + (a - activeStart)] !== groupDelta[g] - ) { + for (let a = 0; a < activeLength && same; a++) { + const g = activeGroups[activeStart + a]; + if (groupLast[g] > t && candidateDeltas[c * activeLength + a] !== groupDelta[g]) { same = false; } } @@ -869,9 +971,9 @@ export class TabFingeringRun { unplayable, moved, rest, - cUnplayable[slot], - cMoved[slot], - cRest[slot] + candidateUnplayable[slot], + candidateMoved[slot], + candidateRest[slot] ) ) { write = slot; @@ -879,38 +981,18 @@ export class TabFingeringRun { } else if (candidateCount < beamWidth) { write = candidateCount; candidateCount++; - if (cUnplayable.length < candidateCount) { - cUnplayable.push(0); - cMoved.push(0); - cRest.push(0); - cCenter.push(0); - cBack.push(0); - cSequence.push(0); - } - while (cDeltas.length < candidateCount * activeLength) { - cDeltas.push(0); - } } else { let worst = 0; for (let c = 1; c < candidateCount; c++) { if ( - TabFingeringRun._isBetter( - cUnplayable[worst], - cMoved[worst], - cRest[worst], - cUnplayable[c], - cMoved[c], - cRest[c] - ) || - (TabFingeringRun._isEqual( - cUnplayable[worst], - cMoved[worst], - cRest[worst], - cUnplayable[c], - cMoved[c], - cRest[c] - ) && - cSequence[c] > cSequence[worst]) + TabFingeringRun._isCandidateBefore( + worst, + c, + candidateUnplayable, + candidateMoved, + candidateRest, + candidateSequence + ) ) { worst = c; } @@ -920,9 +1002,9 @@ export class TabFingeringRun { unplayable, moved, rest, - cUnplayable[worst], - cMoved[worst], - cRest[worst] + candidateUnplayable[worst], + candidateMoved[worst], + candidateRest[worst] ) ) { write = worst; @@ -930,22 +1012,22 @@ export class TabFingeringRun { } if (write >= 0) { - cUnplayable[write] = unplayable; - cMoved[write] = moved; - cRest[write] = rest; - cCenter[write] = this._scoreCenter; - cBack[write] = previousState; - cSequence[write] = sequence; - for (let a = activeStart; a < activeEnd; a++) { - cDeltas[write * activeLength + (a - activeStart)] = groupDelta[this._activeGroups[a]]; + candidateUnplayable[write] = unplayable; + candidateMoved[write] = moved; + candidateRest[write] = rest; + candidateCenter[write] = this._scoreCenter; + candidateBack[write] = p; + candidateSequence[write] = sequence; + for (let a = 0; a < activeLength; a++) { + candidateDeltas[write * activeLength + a] = groupDelta[activeGroups[activeStart + a]]; } } sequence++; // next combination of the new groups' options - let n = newGroups.length - 1; + let n = newCount - 1; while (n >= 0) { - const g = newGroups[n]; + const g = newGroupIds[newStart + n]; choice[n]++; if (choice[n] < this._groupOptionBase[g + 1] - this._groupOptionBase[g]) { break; @@ -959,69 +1041,77 @@ export class TabFingeringRun { } } - // commit the candidates best first - stateBase.push(stUnplayable.length); - stateCount.push(candidateCount); - const committed: boolean[] = new Array(candidateCount).fill(false); + // the candidates become the states of this slice, best first + candidateCommitted.fill(0); for (let k = 0; k < candidateCount; k++) { let best = -1; for (let c = 0; c < candidateCount; c++) { - if (committed[c]) { - continue; - } if ( - best < 0 || - TabFingeringRun._isBetter( - cUnplayable[c], - cMoved[c], - cRest[c], - cUnplayable[best], - cMoved[best], - cRest[best] - ) || - (TabFingeringRun._isEqual( - cUnplayable[c], - cMoved[c], - cRest[c], - cUnplayable[best], - cMoved[best], - cRest[best] - ) && - cSequence[c] < cSequence[best]) + candidateCommitted[c] === 0 && + (best < 0 || + TabFingeringRun._isCandidateBefore( + c, + best, + candidateUnplayable, + candidateMoved, + candidateRest, + candidateSequence + )) ) { best = c; } } - committed[best] = true; - stUnplayable.push(cUnplayable[best]); - stMoved.push(cMoved[best]); - stRest.push(cRest[best]); - stCenter.push(cCenter[best]); - stBack.push(cBack[best]); - stDeltaBase.push(stDeltas.length); + candidateCommitted[best] = 1; + stateUnplayable[k] = candidateUnplayable[best]; + stateMoved[k] = candidateMoved[best]; + stateRest[k] = candidateRest[best]; + stateCenter[k] = candidateCenter[best]; + back[t * beamWidth + k] = candidateBack[best]; for (let a = 0; a < activeLength; a++) { - stDeltas.push(cDeltas[best * activeLength + a]); + stateDeltas[k * activeLength + a] = candidateDeltas[best * activeLength + a]; + } + for (let j = 0; j < newCount; j++) { + newDeltas[newStart * beamWidth + k * newCount + j] = + candidateDeltas[best * activeLength + newGroupPositions[newStart + j]]; } } + stateCount = candidateCount; } // follow the best path back, each group takes the delta chosen in its first slice - const result: number[] = new Array(this._groupCount).fill(0); - let state = sliceCount > 0 ? stateBase[sliceCount - 1] : -1; - for (let t = sliceCount - 1; t >= 0 && state >= 0; t--) { - const activeStart = this._activeBase[t]; - const activeEnd = this._activeBase[t + 1]; - for (let a = activeStart; a < activeEnd; a++) { - const g = this._activeGroups[a]; - if (this._groupFirst[g] === t) { - result[g] = stDeltas[stDeltaBase[state] + (a - activeStart)]; - } + const result = new Int32Array(groupCount); + let state = 0; + for (let t = sliceCount - 1; t >= 0; t--) { + const newStart = newGroupBase[t]; + const newCount = newGroupBase[t + 1] - newStart; + for (let j = 0; j < newCount; j++) { + result[newGroupIds[newStart + j]] = newDeltas[newStart * beamWidth + state * newCount + j]; } - state = stBack[state]; + state = back[t * beamWidth + state]; } return result; } + /** + * Whether candidate a ranks before candidate b: better costs, then generated earlier. + */ + private static _isCandidateBefore( + a: number, + b: number, + unplayable: Int32Array, + moved: Int32Array, + rest: number[], + sequence: Int32Array + ): boolean { + if (TabFingeringRun._isBetter(unplayable[a], moved[a], rest[a], unplayable[b], moved[b], rest[b])) { + return true; + } + return ( + TabFingeringRun._isEqual(unplayable[a], moved[a], rest[a], unplayable[b], moved[b], rest[b]) && + sequence[a] < sequence[b] + ); + } + private static _isBetter( unplayableA: number, movedA: number, @@ -1056,7 +1146,7 @@ export class TabFingeringRun { private _scoreRest: number = 0; private _scoreCenter: number = -1; - private _scoreSlice(t: number, groupDelta: number[], previousCenter: number, gapQuarters: number): void { + private _scoreSlice(t: number, groupDelta: Int32Array, previousCenter: number, gapQuarters: number): void { const options = this._options; let unplayable = 0; let moved = 0; diff --git a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts index 2b73c04565..275ae2f4e8 100644 --- a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts +++ b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts @@ -151,6 +151,10 @@ describe('TabFingeringSolverTest', () => { expect(display(staffOf('\\transpose -4 12.5{nh}'))).toEqual([['1.6*A']]); }); + it('shows natural harmonics without node on their string as artificial harmonics', () => { + expect(display(staffOf('\\transpose 1 12.6{nh}'))).toEqual([['1.6A']]); + }); + it('ignores the fret of dead notes', () => { const staff = staffOf('\\transpose -4 0.6{x}'); expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); From 081fa086038eef979dad12363a539a2bafbbcffd Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 14:42:27 +0100 Subject: [PATCH 07/12] docs: document transposed tablature Adds a 'Transposed tablature' section to the guitar tablature page, the new tabUnplayableFretColor to the palette page, the 1.10 release notes and the behavior to the transpositionPitches JSDoc. --- packages/alphatab/src/NotationSettings.ts | 3 +++ .../src/generated/NotationSettingsJson.ts | 3 +++ .../features/play-sync/per-track-mixing.mdx | 1 + .../docs/features/render/guitar-tablature.mdx | 26 +++++++++++++++++-- .../features/render/score-wide-palette.mdx | 1 + website/docs/releases/release1_10.mdx | 24 +++++++++++++++++ website/static/llms.txt | 2 +- 7 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 website/docs/releases/release1_10.mdx diff --git a/packages/alphatab/src/NotationSettings.ts b/packages/alphatab/src/NotationSettings.ts index fcb6f41b1a..848d8a81ad 100644 --- a/packages/alphatab/src/NotationSettings.ts +++ b/packages/alphatab/src/NotationSettings.ts @@ -534,6 +534,9 @@ export class NotationSettings { * @remarks * This setting allows transposing of tracks for display and playback. * The `transpositionPitches` setting allows defining an additional pitch offset per track, that is then considered when displaying the music sheet. + * + * {@since 1.10.0} Guitar tabs of transposed tracks move notes to other strings when the shifted fret is not playable + * on their string. Notes which fit on no string keep their string and are painted in `display.resources.tabUnplayableFretColor`. */ public transpositionPitches: number[] = []; diff --git a/packages/alphatab/src/generated/NotationSettingsJson.ts b/packages/alphatab/src/generated/NotationSettingsJson.ts index eef659457b..6bf98f230e 100644 --- a/packages/alphatab/src/generated/NotationSettingsJson.ts +++ b/packages/alphatab/src/generated/NotationSettingsJson.ts @@ -143,6 +143,9 @@ export interface NotationSettingsJson { * @remarks * This setting allows transposing of tracks for display and playback. * The `transpositionPitches` setting allows defining an additional pitch offset per track, that is then considered when displaying the music sheet. + * + * {@since 1.10.0} Guitar tabs of transposed tracks move notes to other strings when the shifted fret is not playable + * on their string. Notes which fit on no string keep their string and are painted in `display.resources.tabUnplayableFretColor`. */ transpositionPitches?: number[]; /** diff --git a/website/docs/features/play-sync/per-track-mixing.mdx b/website/docs/features/play-sync/per-track-mixing.mdx index 73d7afa7f0..dab4ffa3a1 100644 --- a/website/docs/features/play-sync/per-track-mixing.mdx +++ b/website/docs/features/play-sync/per-track-mixing.mdx @@ -55,5 +55,6 @@ api.scoreLoaded.on((score) => { ## Where to look next - [Master and monitoring volumes](./master-and-monitoring-volumes) — the master fader every track feeds into. +- [Transposed tablature](/docs/features/render/guitar-tablature#transposed-tablature) — transpose what's rendered as well, with tab notes moved to playable strings. - [Selecting and switching tracks](/docs/features/import-load/selecting-and-switching-tracks) — control which tracks render on screen, independent of the mix. - [`changeTrackVolume`](/docs/reference/api/changetrackvolume), [`changeTrackSolo`](/docs/reference/api/changetracksolo), [`changeTrackMute`](/docs/reference/api/changetrackmute), and [`changeTrackTranspositionPitch`](/docs/reference/api/changetracktranspositionpitch) reference entries. diff --git a/website/docs/features/render/guitar-tablature.mdx b/website/docs/features/render/guitar-tablature.mdx index be90572325..2abcae2596 100644 --- a/website/docs/features/render/guitar-tablature.mdx +++ b/website/docs/features/render/guitar-tablature.mdx @@ -1,6 +1,6 @@ --- title: "Guitar tablature" -description: "String-and-fret rendering, rhythm modes, small grace tabs." +description: "String-and-fret rendering, rhythm modes, small grace tabs, transposed tabs." sidebar_custom_props: feature_chapter: notation-types feature_order: 20 @@ -8,6 +8,7 @@ keywords: - alphaTab - tablature - guitar + - transpose --- import { AlphaTab } from '@site/src/components/AlphaTab'; @@ -41,6 +42,27 @@ When you hide standard notation, the tab staff loses stems and beams. Turn them Because these are settings on the `notation` group, they apply to every staff in the render. Combine them with per-staff `showTablature` toggles when you need mixed layouts. +## Transposed tablature {#transposed-tablature} + +[`notation.transpositionPitches`](/docs/reference/settings/notation/transpositionpitches) shifts a track by a number of semitones for display and playback. On the tab staff, a note keeps its string and fret position shifted by the transposition while that fret is playable. When the fret would drop below the open string or rise beyond the 24th fret, alphaTab moves the note to another string. It picks the position which keeps the hand closest to the surrounding notes and keeps chord notes on separate strings. + +Notes connected by ties, slides, and hammer-ons or pull-offs move together, so they stay on one string. Bends, slides, and vibrato never land on an open string. Natural harmonics move to the node that sounds the transposed pitch. When no string has such a node, the tab shows an artificial harmonic an octave above the fretted note. + +The example below is transposed down four semitones. The open strings and the low notes no longer fit on their strings: + +{` +\\track "Guitar" + \\staff{score tabs} + :4 0.6 3.5 2.4 0.3 | (0.1 0.2 0.3) 3.5 3.5 3.5 | 3.5{t} 2.3{h} 4.3 4.3{b (0 4)} +`} + +A note that fits on no string of the tuning keeps its string and shows the out-of-range fret in [`display.resources.tabUnplayableFretColor`](/docs/reference/types/renderingresources/). The low E above is such a note. + +The new positions exist only on the rendered tab. The loaded score keeps its strings and frets, and changing `transpositionPitches` at runtime takes effect on the next `render()`. Frets count from the capo, so a capo lowers the highest usable fret. String number circles in the standard notation follow the moved strings, and left-hand finger numbers of moved notes are hidden. Chord diagrams are not transposed. + ## Show it in code ```js @@ -74,5 +96,5 @@ api.scoreLoaded.on((score) => { - [Standard notation](/docs/features/render/standard-notation) — pair the tab staff with a score staff. - [Slash notation](/docs/features/render/slash-notation) — swap fret numbers for chord-rhythm slashes. - [Drum tablature](/docs/features/render/drum-tabs#drum-tablature) — the same tab staff for percussion tracks. -- [`notation.rhythmMode`](/docs/reference/settings/notation/rhythmmode), [`notation.rhythmHeight`](/docs/reference/settings/notation/rhythmheight), and [`notation.smallGraceTabNotes`](/docs/reference/settings/notation/smallgracetabnotes) in the settings reference. +- [`notation.rhythmMode`](/docs/reference/settings/notation/rhythmmode), [`notation.rhythmHeight`](/docs/reference/settings/notation/rhythmheight), [`notation.smallGraceTabNotes`](/docs/reference/settings/notation/smallgracetabnotes), and [`notation.transpositionPitches`](/docs/reference/settings/notation/transpositionpitches) in the settings reference. - [`Staff.showTablature`](/docs/reference/types/model/staff) in the model reference. diff --git a/website/docs/features/render/score-wide-palette.mdx b/website/docs/features/render/score-wide-palette.mdx index df5f56b10e..35af7b1264 100644 --- a/website/docs/features/render/score-wide-palette.mdx +++ b/website/docs/features/render/score-wide-palette.mdx @@ -28,6 +28,7 @@ Each color on [`RenderingResources`](/docs/reference/types/renderingresources/) - `mainGlyphColor` — noteheads, stems, beams, and effect glyphs of the primary voice. - `secondaryGlyphColor` — the same glyphs when they belong to a secondary voice; defaults to a semi-transparent black so lower voices sit visually behind the main line. - `scoreInfoColor` — the title, subtitle, artist, album, and copyright text. +- `tabUnplayableFretColor` — tab fret numbers that fit on no string after [transposing the track](/docs/features/render/guitar-tablature#transposed-tablature). The [`RenderingResources`](/docs/reference/types/renderingresources/) reference lists every field, including the font counterparts (`barNumberFont`, `copyrightFont`, and so on) that pair with each color. diff --git a/website/docs/releases/release1_10.mdx b/website/docs/releases/release1_10.mdx new file mode 100644 index 0000000000..f1730c1bd2 --- /dev/null +++ b/website/docs/releases/release1_10.mdx @@ -0,0 +1,24 @@ +--- +title: v1.10 +--- + +import { AlphaTab } from '@site/src/components/AlphaTab'; + +## 1.10.0 + +### Music Notation + +#### render: transposed tabs on playable strings + +Guitar tabs of a track transposed with [`notation.transpositionPitches`](/docs/reference/settings/notation/transpositionpitches) (or the alphaTex `\transpose` metadata tag) no longer show negative frets or frets beyond the neck. A note keeps its string while the shifted fret is playable there; otherwise it moves to another string, together with the notes it is tied, slid, or hammered to. Natural harmonics move to the node of the transposed pitch. Notes that fit on no string keep their string and show the fret in the new [`display.resources.tabUnplayableFretColor`](/docs/reference/types/renderingresources/). + +{` +\\track "Guitar" + \\staff{score tabs} + :4 0.6 3.5 2.4 0.3 | (0.1 0.2 0.3) 3.5 3.5 3.5 | 3.5{t} 2.3{h} 4.3 4.3{b (0 4)} +`} + +The loaded score is not changed: the new positions exist only on the rendered tab. Details: [Transposed tablature](/docs/features/render/guitar-tablature#transposed-tablature). diff --git a/website/static/llms.txt b/website/static/llms.txt index bc8fc31503..d23737ffc9 100644 --- a/website/static/llms.txt +++ b/website/static/llms.txt @@ -60,7 +60,7 @@ alphaTab is not a drop-in widget — it exposes an API you build your own score - [Responsive resize](https://alphatab.net/docs/features/render/responsive-resize): ResizeObserver, triggerResize(), resize event. - [Rendering a slice](https://alphatab.net/docs/features/render/bar-range): startBar / barCount to render partial scores. - [Standard notation](https://alphatab.net/docs/features/render/standard-notation): The traditional five-line staff, showStandardNotation. -- [Guitar tablature](https://alphatab.net/docs/features/render/guitar-tablature): String-and-fret rendering, rhythm modes, small grace tabs. +- [Guitar tablature](https://alphatab.net/docs/features/render/guitar-tablature): String-and-fret rendering, rhythm modes, small grace tabs, transposed tabs. - [Slash notation](https://alphatab.net/docs/features/render/slash-notation): Chord rhythm slashes, showSlash. - [Numbered notation (jiǎnpǔ)](https://alphatab.net/docs/features/render/numbered-notation): Cipher notation, showNumbered. - [Drum and percussion notation](https://alphatab.net/docs/features/render/drum-tabs): Percussion staff with 1/2/3 lines, drum piece heads. From 486dfc9107eedd3790fac3c08d8f6de6f4a21c24 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 15:49:19 +0100 Subject: [PATCH 08/12] perf(rendering): avoid a closure per beat in the harmonics effect check --- .../src/rendering/effects/HarmonicsEffectInfo.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts b/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts index 78f9846730..9b6dd75063 100644 --- a/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts @@ -66,6 +66,17 @@ function displayedHarmonicType(renderer: BarRendererBase, note: Note): HarmonicT return note.harmonicType; } +function hasDisplayedHarmonic(renderer: BarRendererBase, beat: Beat, harmonicType: HarmonicType): boolean { + const notes = beat.notes; + for (let i = 0; i < notes.length; i++) { + const note = notes[i]; + if (note.isHarmonic && displayedHarmonicType(renderer, note) === harmonicType) { + return true; + } + } + return false; +} + /** * @internal */ @@ -76,7 +87,7 @@ export function createHarmonicsEffectInfo(harmonicType: HarmonicType): EffectInf hideOnMultiTrack: false, sizingMode: EffectBarGlyphSizing.GroupedOnBeat, shouldCreateGlyph: (renderer: BarRendererBase, beat: Beat): boolean => - beat.notes.some(note => note.isHarmonic && displayedHarmonicType(renderer, note) === harmonicType), + hasDisplayedHarmonic(renderer, beat, harmonicType), createNewGlyph: (_renderer: BarRendererBase, _beat: Beat): EffectGlyph => new LineRangedGlyph(harmonicToString(harmonicType), NotationElement.EffectHarmonics), canExpand: (_from: Beat, _to: Beat): boolean => true, From a9e9fa6f08e3dba82c3c1d0269e015a1821f98d0 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 15:56:49 +0100 Subject: [PATCH 09/12] perf(rendering): avoid boxing in the tab fingering search, skip run setup for unchanged segments Costs are compared by candidate slot and passed to and from the slice scoring through an array, so no doubles cross function boundaries. The fast path runs before the solver state is created, so segments keeping their fingering allocate nothing. Back pointers are stored as bytes. --- .../src/rendering/utils/TabFingeringSolver.ts | 167 +++++++++--------- 1 file changed, 80 insertions(+), 87 deletions(-) diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts index 95eb432a9b..31f632e5ea 100644 --- a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts +++ b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts @@ -31,6 +31,7 @@ export class TabFingeringOptions { public occupancyPenalty: number = 8; public asArtificialPenalty: number = 20; public handMovementWeight: number = 1; + /** The states kept per time slice, at most 255. */ public beamWidth: number = 16; public maxLeavesPerState: number = 256; } @@ -197,13 +198,11 @@ export class TabFingeringSolver { lastBarIndex: number, options?: TabFingeringOptions ): TabFingeringSegment | null { - const run = new TabFingeringRun( - staff, - firstBarIndex, - lastBarIndex, - options ?? TabFingeringSolver._defaultOptions - ); - return run.solve(); + const resolvedOptions = options ?? TabFingeringSolver._defaultOptions; + if (TabFingeringRun.isIdentity(staff, firstBarIndex, lastBarIndex, resolvedOptions)) { + return null; + } + return new TabFingeringRun(staff, firstBarIndex, lastBarIndex, resolvedOptions).solve(); } /** @@ -305,10 +304,10 @@ export class TabFingeringRun { this._stringCount = staff.tuning.length; } - public solve(): TabFingeringSegment | null { - if (this._isIdentity()) { - return null; - } + /** + * Solves the bars, which must not be playable as they are (see {@link isIdentity}). + */ + public solve(): TabFingeringSegment { this._collectNotes(); this._buildGroups(); @@ -499,17 +498,22 @@ export class TabFingeringRun { * natural harmonics on a node of their string. Reads the model directly to allocate nothing for * the common case. */ - private _isIdentity(): boolean { - const staff = this._staff; + public static isIdentity( + staff: Staff, + firstBarIndex: number, + lastBarIndex: number, + options: TabFingeringOptions + ): boolean { const transpositionPitch = staff.transpositionPitch; - for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { + const stringCount = staff.tuning.length; + for (let b = firstBarIndex; b <= lastBarIndex; b++) { for (let v = 0; v < staff.bars[b].voices.length; v++) { const voice = staff.bars[b].voices[v]; for (let k = 0; k < voice.beats.length; k++) { const beat = voice.beats[k]; for (let n = 0; n < beat.notes.length; n++) { const note = beat.notes[n]; - if (!note.isStringed || note.string < 1 || note.string > this._stringCount || note.isDead) { + if (!note.isStringed || note.string < 1 || note.string > stringCount || note.isDead) { continue; } if (TabFingeringSolver.isNaturalHarmonic(note)) { @@ -518,7 +522,7 @@ export class TabFingeringRun { } continue; } - const maxFret = Math.max(this._options.defaultMaxFret - this._capo, note.fret); + const maxFret = Math.max(options.defaultMaxFret - staff.capo, note.fret); if ( !TabFingeringRun._isPlayableFret( note.fret - transpositionPitch, @@ -840,7 +844,8 @@ export class TabFingeringRun { */ private _search(): Int32Array { const options = this._options; - const beamWidth = options.beamWidth; + // back pointers are stored as bytes + const beamWidth = Math.min(options.beamWidth, 255); const sliceCount = this._sliceTick.length; const groupCount = this._groupCount; const activeBase = this._activeBase; @@ -883,18 +888,21 @@ export class TabFingeringRun { const stateDeltas = new Int8Array(beamWidth * maxActive); let stateCount = 0; - // the unsorted candidates of the current slice - const candidateUnplayable = new Int32Array(beamWidth); - const candidateMoved = new Int32Array(beamWidth); - const candidateRest: number[] = new Array(beamWidth).fill(0); - const candidateCenter: number[] = new Array(beamWidth).fill(0); + // the unsorted candidates of the current slice, the last slot holds the candidate being scored + // (costs are compared by slot, passing doubles between functions would box them) + const scored = beamWidth; + const candidateUnplayable = new Int32Array(beamWidth + 1); + const candidateMoved = new Int32Array(beamWidth + 1); + const candidateRest: number[] = new Array(beamWidth + 1).fill(0); + const candidateCenter: number[] = new Array(beamWidth + 1).fill(0); const candidateBack = new Int32Array(beamWidth); - const candidateSequence = new Int32Array(beamWidth); + const candidateSequence = new Int32Array(beamWidth + 1); + const scores = this._scores; const candidateDeltas = new Int8Array(beamWidth * maxActive); const candidateCommitted = new Uint8Array(beamWidth); // kept for the path back - const back = new Int32Array(sliceCount * beamWidth); + const back = new Uint8Array(sliceCount * beamWidth); const newDeltas = new Int8Array(groupCount * beamWidth); const groupDelta = new Int32Array(groupCount); @@ -912,19 +920,19 @@ export class TabFingeringRun { const previousCount = t === 0 ? 1 : stateCount; const previousActiveStart = t === 0 ? 0 : activeBase[t - 1]; const previousActiveLength = t === 0 ? 0 : activeStart - previousActiveStart; - const gapQuarters = + scores[TabFingeringRun._scoreGapQuarters] = t === 0 ? 0 : (this._sliceTick[t] - this._sliceTick[t - 1]) / TabFingeringRun._ticksPerQuarter; for (let p = 0; p < previousCount; p++) { let previousUnplayable = 0; let previousMoved = 0; let previousRest = 0; - let previousCenter = -1; + scores[TabFingeringRun._scorePreviousCenter] = -1; if (t > 0) { previousUnplayable = stateUnplayable[p]; previousMoved = stateMoved[p]; previousRest = stateRest[p]; - previousCenter = stateCenter[p]; + scores[TabFingeringRun._scorePreviousCenter] = stateCenter[p]; // groups continuing from the previous slice keep their delta for (let a = 0; a < previousActiveLength; a++) { groupDelta[activeGroups[previousActiveStart + a]] = stateDeltas[p * previousActiveLength + a]; @@ -944,10 +952,12 @@ export class TabFingeringRun { } leaves++; - this._scoreSlice(t, groupDelta, previousCenter, gapQuarters); - const unplayable = previousUnplayable + this._scoreUnplayable; - const moved = previousMoved + this._scoreMoved; - const rest = previousRest + this._scoreRest; + this._scoreSlice(t, groupDelta); + candidateUnplayable[scored] = previousUnplayable + this._scoreUnplayable; + candidateMoved[scored] = previousMoved + this._scoreMoved; + candidateRest[scored] = previousRest + scores[TabFingeringRun._scoreRest]; + candidateCenter[scored] = scores[TabFingeringRun._scoreCenter]; + candidateSequence[scored] = sequence; // candidates are interchangeable for later slices if all continuing groups agree let slot = -1; @@ -967,13 +977,13 @@ export class TabFingeringRun { let write = -1; if (slot >= 0) { if ( - TabFingeringRun._isBetter( - unplayable, - moved, - rest, - candidateUnplayable[slot], - candidateMoved[slot], - candidateRest[slot] + TabFingeringRun._isCandidateBefore( + scored, + slot, + candidateUnplayable, + candidateMoved, + candidateRest, + candidateSequence ) ) { write = slot; @@ -998,13 +1008,13 @@ export class TabFingeringRun { } } if ( - TabFingeringRun._isBetter( - unplayable, - moved, - rest, - candidateUnplayable[worst], - candidateMoved[worst], - candidateRest[worst] + TabFingeringRun._isCandidateBefore( + scored, + worst, + candidateUnplayable, + candidateMoved, + candidateRest, + candidateSequence ) ) { write = worst; @@ -1012,10 +1022,10 @@ export class TabFingeringRun { } if (write >= 0) { - candidateUnplayable[write] = unplayable; - candidateMoved[write] = moved; - candidateRest[write] = rest; - candidateCenter[write] = this._scoreCenter; + candidateUnplayable[write] = candidateUnplayable[scored]; + candidateMoved[write] = candidateMoved[scored]; + candidateRest[write] = candidateRest[scored]; + candidateCenter[write] = candidateCenter[scored]; candidateBack[write] = p; candidateSequence[write] = sequence; for (let a = 0; a < activeLength; a++) { @@ -1103,50 +1113,31 @@ export class TabFingeringRun { rest: number[], sequence: Int32Array ): boolean { - if (TabFingeringRun._isBetter(unplayable[a], moved[a], rest[a], unplayable[b], moved[b], rest[b])) { - return true; + if (unplayable[a] !== unplayable[b]) { + return unplayable[a] < unplayable[b]; } - return ( - TabFingeringRun._isEqual(unplayable[a], moved[a], rest[a], unplayable[b], moved[b], rest[b]) && - sequence[a] < sequence[b] - ); - } - - private static _isBetter( - unplayableA: number, - movedA: number, - restA: number, - unplayableB: number, - movedB: number, - restB: number - ): boolean { - if (unplayableA !== unplayableB) { - return unplayableA < unplayableB; + if (moved[a] !== moved[b]) { + return moved[a] < moved[b]; } - if (movedA !== movedB) { - return movedA < movedB; + if (rest[a] !== rest[b]) { + return rest[a] < rest[b]; } - return restA < restB; + return sequence[a] < sequence[b]; } - private static _isEqual( - unplayableA: number, - movedA: number, - restA: number, - unplayableB: number, - movedB: number, - restB: number - ): boolean { - return unplayableA === unplayableB && movedA === movedB && restA === restB; - } + // inputs and results of _scoreSlice which are no integers + private static readonly _scorePreviousCenter: number = 0; + private static readonly _scoreGapQuarters: number = 1; + private static readonly _scoreRest: number = 2; + private static readonly _scoreCenter: number = 3; + private readonly _scores: number[] = [0, 0, 0, 0]; - // results of _scoreSlice private _scoreUnplayable: number = 0; private _scoreMoved: number = 0; - private _scoreRest: number = 0; - private _scoreCenter: number = -1; - private _scoreSlice(t: number, groupDelta: Int32Array, previousCenter: number, gapQuarters: number): void { + private _scoreSlice(t: number, groupDelta: Int32Array): void { + const scores = this._scores; + const previousCenter = scores[TabFingeringRun._scorePreviousCenter]; const options = this._options; let unplayable = 0; let moved = 0; @@ -1216,13 +1207,15 @@ export class TabFingeringRun { } center = fretSum / frettedCount; if (previousCenter >= 0) { - rest += (Math.abs(center - previousCenter) * options.handMovementWeight) / (1 + gapQuarters); + rest += + (Math.abs(center - previousCenter) * options.handMovementWeight) / + (1 + scores[TabFingeringRun._scoreGapQuarters]); } } this._scoreUnplayable = unplayable; this._scoreMoved = moved; - this._scoreRest = rest; - this._scoreCenter = center; + scores[TabFingeringRun._scoreRest] = rest; + scores[TabFingeringRun._scoreCenter] = center; } } From 617cbf29467e2620b6ad4b852b60605e689307d0 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 16:18:29 +0100 Subject: [PATCH 10/12] refactor(rendering): place transposed tab notes per beat while laying out the tab Replaces the segment-wide beam search (TabFingeringSolver, TabFingeringSegment) by TabFingering, which decides the string of each note while TabBeatGlyph creates its note glyphs and keeps the result on the NoteNumberGlyph. It only reads the beat, the glyphs of earlier beats and the tie/slide/hammer-on links of the notes: continued notes follow their origin, notes playable on their string keep it, the others take the free string closest to the frets of the beat or the previous beat. Natural harmonics without a node at the transposed pitch are marked unplayable instead of being shown as artificial harmonics. --- .../alphatab/src/rendering/TabBarRenderer.ts | 212 +-- .../rendering/effects/FingeringEffectInfo.ts | 11 +- .../rendering/effects/HarmonicsEffectInfo.ts | 33 +- .../rendering/glyphs/FingeringGroupGlyph.ts | 3 +- .../src/rendering/glyphs/NoteNumberGlyph.ts | 56 +- .../glyphs/StringNumberContainerGlyph.ts | 3 +- .../src/rendering/glyphs/TabBeatGlyph.ts | 20 +- .../src/rendering/glyphs/TabNoteChordGlyph.ts | 43 +- .../rendering/layout/VerticalLayoutBase.ts | 4 +- .../src/rendering/utils/TabFingering.ts | 280 ++++ .../rendering/utils/TabFingeringSegment.ts | 90 -- .../src/rendering/utils/TabFingeringSolver.ts | 1221 ----------------- .../guitar-tabs/transpose-down.png | Bin 26391 -> 26522 bytes .../test/rendering/TabFingering.test.ts | 133 ++ .../test/rendering/TabFingeringSolver.test.ts | 199 --- .../docs/features/render/guitar-tablature.mdx | 4 +- 16 files changed, 536 insertions(+), 1776 deletions(-) create mode 100644 packages/alphatab/src/rendering/utils/TabFingering.ts delete mode 100644 packages/alphatab/src/rendering/utils/TabFingeringSegment.ts delete mode 100644 packages/alphatab/src/rendering/utils/TabFingeringSolver.ts create mode 100644 packages/alphatab/test/rendering/TabFingering.test.ts delete mode 100644 packages/alphatab/test/rendering/TabFingeringSolver.test.ts diff --git a/packages/alphatab/src/rendering/TabBarRenderer.ts b/packages/alphatab/src/rendering/TabBarRenderer.ts index 92e0bec6ef..0a27c42f1c 100644 --- a/packages/alphatab/src/rendering/TabBarRenderer.ts +++ b/packages/alphatab/src/rendering/TabBarRenderer.ts @@ -2,7 +2,7 @@ import { BarSubElement } from '@coderline/alphatab/model/Bar'; import { type Beat, BeatSubElement } from '@coderline/alphatab/model/Beat'; import type { ElementDisplay } from '@coderline/alphatab/model/ElementDisplay'; import { GraceType } from '@coderline/alphatab/model/GraceType'; -import { Note } from '@coderline/alphatab/model/Note'; +import type { Note } from '@coderline/alphatab/model/Note'; import type { BarNumberDisplay } from '@coderline/alphatab/model/RenderStylesheet'; import type { Voice } from '@coderline/alphatab/model/Voice'; import { TabRhythmMode } from '@coderline/alphatab/NotationSettings'; @@ -25,8 +25,8 @@ import { BeamDirection } from '@coderline/alphatab/rendering/utils/BeamDirection import type { BeamingHelper } from '@coderline/alphatab/rendering/utils/BeamingHelper'; import { ElementStyleHelper } from '@coderline/alphatab/rendering/utils/ElementStyleHelper'; import type { ScrambledPath } from '@coderline/alphatab/rendering/utils/ScrambledPath'; -import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; -import { TabFingeringSolver } from '@coderline/alphatab/rendering/utils/TabFingeringSolver'; +import { TabFingering } from '@coderline/alphatab/rendering/utils/TabFingering'; +import type { NoteNumberGlyph } from '@coderline/alphatab/rendering/glyphs/NoteNumberGlyph'; /** * This BarRenderer renders a bar using guitar tablature notation @@ -143,207 +143,69 @@ export class TabBarRenderer extends LineBarRenderer { } /** - * The display fingering of the transposed segment this bar belongs to, null if all notes - * keep their model string. + * The glyph showing the given note in the tab of its bar, null if the note is not shown. */ - public fingering: TabFingeringSegment | null = null; - - /** - * The last bar of the segment this bar belongs to when all its notes keep their model string, -1 otherwise. - */ - public identityUntilBarIndex: number = -1; - - private _isFingeringActive: boolean = false; - - private _resolveFingering(): void { - const staff = this.bar.staff; - this.fingering = null; - this.identityUntilBarIndex = -1; - this._isFingeringActive = TabFingeringSolver.isActive(staff); - if (!this._isFingeringActive) { - return; - } - - const barIndex = this.bar.index; - const previous = this.previousRenderer; - if (previous instanceof TabBarRenderer) { - const previousFingering = previous.fingering; - if (previousFingering !== null && previousFingering.covers(barIndex)) { - this.fingering = previousFingering; - return; - } - if (previous.identityUntilBarIndex >= barIndex) { - this.identityUntilBarIndex = previous.identityUntilBarIndex; - return; - } - } - - const lastBarIndex = TabFingeringSolver.segmentEnd(staff, barIndex); - this.fingering = TabFingeringSolver.solve(staff, barIndex, lastBarIndex); - if (this.fingering === null) { - this.identityUntilBarIndex = lastBarIndex; - } - } - - protected override createBeatGlyphs(): void { - this._resolveFingering(); - super.createBeatGlyphs(); - } - - private _fingeringFor(note: Note): TabFingeringSegment | null { + public getNoteGlyph(note: Note): NoteNumberGlyph | null { const bar = note.beat.voice.bar; - const own = this.fingering; - if (own !== null && own.covers(bar.index)) { - return own; - } - if (bar === this.bar) { - return null; - } - const renderer = this.scoreRenderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar); - if (renderer instanceof TabBarRenderer) { - const fingering = renderer.fingering; - if (fingering !== null && fingering.covers(bar.index)) { - return fingering; - } - } - return null; + // a renderer is registered in the layout only after its own layout + const renderer = + bar === this.bar ? this : this.scoreRenderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar); + const container = renderer instanceof TabBarRenderer ? renderer.getBeatContainer(note.beat) : undefined; + const noteNumbers = container + ? ((container as TabBeatContainerGlyph).onNotes as TabBeatGlyph).noteNumbers + : null; + return noteNumbers ? noteNumbers.findNoteGlyph(note) : null; } /** - * The string (1 = lowest) on which the note is shown in this tab. + * The string (1 = lowest) on which the note is shown, see {@link TabFingering}. */ public getDisplayString(note: Note): number { - if (!this._isFingeringActive || !note.isStringed) { - return note.string; - } - const fingering = this._fingeringFor(note); - return fingering !== null ? fingering.getString(note) : note.string; + const glyph = this.getNoteGlyph(note); + return glyph !== null && glyph.displayString > 0 ? glyph.displayString : note.string; } /** - * The fret shown for the note: the natural harmonic node for natural harmonics, the base fret otherwise. + * The fret shown for the note, the node for natural harmonics. */ public getDisplayFret(note: Note): number { - const staff = note.beat.voice.bar.staff; - const isNaturalHarmonic = TabFingeringSolver.isNaturalHarmonic(note); - if (!this._isFingeringActive || !note.isStringed) { - return (isNaturalHarmonic ? note.harmonicValue : note.fret) - staff.transpositionPitch; - } - const fingering = this._fingeringFor(note); - if (fingering === null) { - if (isNaturalHarmonic) { - const modelStringNode = TabFingeringSolver.findNaturalNodeOnModelString(note); - return modelStringNode >= 0 - ? TabFingeringSolver.naturalNodeValues[modelStringNode] - : note.harmonicValue - staff.transpositionPitch; - } - return note.fret - staff.transpositionPitch; - } - const node = fingering.getNode(note); - return node >= 0 ? TabFingeringSolver.naturalNodeValues[node] : fingering.getFret(note); - } - - /** - * The combination of {@link TabFingeringSegment} flags describing how the note differs from the model. - */ - public getDisplayFlags(note: Note): number { - if (!this._isFingeringActive || !note.isStringed) { - return 0; - } - const fingering = this._fingeringFor(note); - return fingering !== null ? fingering.getFlags(note) : 0; - } - - /** - * The fret of the trill target on the displayed string of the note. - */ - public getDisplayTrillFret(note: Note): number { - const staff = note.beat.voice.bar.staff; - return ( - note.trillValue - - staff.transpositionPitch - - (staff.capo + Note.getStringTuning(staff, this.getDisplayString(note))) - ); + const glyph = this.getNoteGlyph(note); + return glyph !== null && glyph.displayString > 0 + ? glyph.displayFret + : note.fret - note.beat.voice.bar.staff.transpositionPitch; } /** * The stringed note of the beat shown on the highest string. */ public getDisplayMaxStringNote(beat: Beat): Note | null { - if (!this._isFingeringActive) { - return beat.maxStringNote; - } - let result: Note | null = null; - let resultString = 0; - for (const note of beat.notes) { - if (!note.isStringed) { - continue; - } - const str = this.getDisplayString(note); - if (result === null || str > resultString) { - result = note; - resultString = str; - } - } - return result; + const container = this.getBeatContainer(beat); + const noteNumbers = container + ? ((container as TabBeatContainerGlyph).onNotes as TabBeatGlyph).noteNumbers + : null; + return noteNumbers ? noteNumbers.maxStringNote : beat.maxStringNote; } /** * The stringed note of the beat shown on the lowest string. */ public getDisplayMinStringNote(beat: Beat): Note | null { - if (!this._isFingeringActive) { - return beat.minStringNote; - } - let result: Note | null = null; - let resultString = 0; - for (const note of beat.notes) { - if (!note.isStringed) { - continue; - } - const str = this.getDisplayString(note); - if (result === null || str < resultString) { - result = note; - resultString = str; - } - } - return result; - } - - /** - * The string on which the given note is shown in the tab of its staff, for renderers of other notations. - */ - public static resolveDisplayString(renderer: BarRendererBase, note: Note): number { - if (!TabFingeringSolver.isActive(note.beat.voice.bar.staff)) { - return note.string; - } - const tab = TabBarRenderer._tabRendererOf(renderer, note); - return tab !== null ? tab.getDisplayString(note) : note.string; - } - - // a renderer is registered in the layout only after its own layout - private static _tabRendererOf(renderer: BarRendererBase, note: Note): TabBarRenderer | null { - const bar = note.beat.voice.bar; - if (renderer instanceof TabBarRenderer && renderer.bar === bar) { - return renderer; - } - const tab = renderer.scoreRenderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar); - return tab instanceof TabBarRenderer ? tab : null; + const container = this.getBeatContainer(beat); + const noteNumbers = container + ? ((container as TabBeatContainerGlyph).onNotes as TabBeatGlyph).noteNumbers + : null; + return noteNumbers ? noteNumbers.minStringNote : beat.minStringNote; } /** - * Whether the tab of the note's staff shows it on another string or as open string, so left-hand - * fingerings of the model do not apply to it. + * The tab glyph of the note for renderers of other notations, resolved on paint when all tab bars are laid out. */ - public static isFingeringChanged(renderer: BarRendererBase, note: Note): boolean { - if (!note.isStringed || !TabFingeringSolver.isActive(note.beat.voice.bar.staff)) { - return false; - } - const tab = TabBarRenderer._tabRendererOf(renderer, note); - if (tab === null) { - return false; + public static findTabNoteGlyph(renderer: BarRendererBase, note: Note): NoteNumberGlyph | null { + if (!TabFingering.isActive(note.beat.voice.bar.staff)) { + return null; } - return (tab.getDisplayFlags(note) & TabFingeringSegment.flagMoved) !== 0 || tab.getDisplayFret(note) === 0; + const tab = renderer.scoreRenderer.layout!.getRendererForBar(TabBarRenderer.StaffId, note.beat.voice.bar); + return tab instanceof TabBarRenderer ? tab.getNoteGlyph(note) : null; } public minString = Number.NaN; diff --git a/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts b/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts index d6a9e0e765..8bb3bd1362 100644 --- a/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/FingeringEffectInfo.ts @@ -2,7 +2,6 @@ import type { Beat } from '@coderline/alphatab/model/Beat'; import { Fingers } from '@coderline/alphatab/model/Fingers'; import type { Note } from '@coderline/alphatab/model/Note'; import { FingeringMode, NotationElement } from '@coderline/alphatab/NotationSettings'; -import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import type { BarRendererBase } from '@coderline/alphatab/rendering/BarRendererBase'; import { EffectBarGlyphSizing } from '@coderline/alphatab/rendering/EffectBarGlyphSizing'; import { EffectBandPlacementCategory, type EffectInfo } from '@coderline/alphatab/rendering/EffectInfo'; @@ -31,15 +30,7 @@ export const fingeringEffectInfo: EffectInfo = { if (beat.notes.length !== 1) { return false; } - const note = beat.notes[0]; - if ( - note.leftHandFinger !== Fingers.Unknown && - renderer instanceof TabBarRenderer && - TabBarRenderer.isFingeringChanged(renderer, note) - ) { - return false; - } - return note.isFingering; + return beat.notes[0].isFingering; }, createNewGlyph: (renderer: BarRendererBase, beat: Beat): EffectGlyph => { let finger: Fingers = Fingers.Unknown; diff --git a/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts b/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts index 9b6dd75063..bb4476e3f9 100644 --- a/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/HarmonicsEffectInfo.ts @@ -5,10 +5,9 @@ import { NotationElement } from '@coderline/alphatab/NotationSettings'; import type { BarRendererBase } from '@coderline/alphatab/rendering/BarRendererBase'; import { EffectBarGlyphSizing } from '@coderline/alphatab/rendering/EffectBarGlyphSizing'; import { EffectBandPlacementCategory, type EffectInfo } from '@coderline/alphatab/rendering/EffectInfo'; +import { createNoteShouldCreateGlyph } from '@coderline/alphatab/rendering/effects/NoteEffectInfoBase'; import type { EffectGlyph } from '@coderline/alphatab/rendering/glyphs/EffectGlyph'; import { LineRangedGlyph } from '@coderline/alphatab/rendering/glyphs/LineRangedGlyph'; -import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; -import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; /** * @internal @@ -52,31 +51,6 @@ function harmonicEffectId(harmonicType: HarmonicType): string { } } -/** - * Natural harmonics without a node on the transposed tab are shown as artificial harmonics. - */ -function displayedHarmonicType(renderer: BarRendererBase, note: Note): HarmonicType { - if ( - note.harmonicType === HarmonicType.Natural && - renderer instanceof TabBarRenderer && - (renderer.getDisplayFlags(note) & TabFingeringSegment.flagAsArtificial) !== 0 - ) { - return HarmonicType.Artificial; - } - return note.harmonicType; -} - -function hasDisplayedHarmonic(renderer: BarRendererBase, beat: Beat, harmonicType: HarmonicType): boolean { - const notes = beat.notes; - for (let i = 0; i < notes.length; i++) { - const note = notes[i]; - if (note.isHarmonic && displayedHarmonicType(renderer, note) === harmonicType) { - return true; - } - } - return false; -} - /** * @internal */ @@ -86,8 +60,9 @@ export function createHarmonicsEffectInfo(harmonicType: HarmonicType): EffectInf notationElement: NotationElement.EffectHarmonics, hideOnMultiTrack: false, sizingMode: EffectBarGlyphSizing.GroupedOnBeat, - shouldCreateGlyph: (renderer: BarRendererBase, beat: Beat): boolean => - hasDisplayedHarmonic(renderer, beat, harmonicType), + shouldCreateGlyph: createNoteShouldCreateGlyph( + (note: Note): boolean => note.isHarmonic && note.harmonicType === harmonicType + ), createNewGlyph: (_renderer: BarRendererBase, _beat: Beat): EffectGlyph => new LineRangedGlyph(harmonicToString(harmonicType), NotationElement.EffectHarmonics), canExpand: (_from: Beat, _to: Beat): boolean => true, diff --git a/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts b/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts index 5d6dfcde62..331cd5e491 100644 --- a/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/FingeringGroupGlyph.ts @@ -201,7 +201,8 @@ export class FingeringGroupGlyph extends GlyphGroup { return false; } for (const note of info.leftHandNotes) { - if (!TabBarRenderer.isFingeringChanged(this.renderer, note)) { + const tabGlyph = TabBarRenderer.findTabNoteGlyph(this.renderer, note); + if (tabGlyph === null || !(tabGlyph.isMoved || tabGlyph.displayFret === 0)) { return false; } } diff --git a/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts b/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts index 372db4191e..97a82d7309 100644 --- a/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/NoteNumberGlyph.ts @@ -3,14 +3,13 @@ import type { Color } from '@coderline/alphatab/model/Color'; import type { Font } from '@coderline/alphatab/model/Font'; import { HarmonicType } from '@coderline/alphatab/model/HarmonicType'; import { ModelUtils } from '@coderline/alphatab/model/ModelUtils'; -import { type Note, NoteSubElement } from '@coderline/alphatab/model/Note'; +import { Note, NoteSubElement } from '@coderline/alphatab/model/Note'; import { PercussionMapper } from '@coderline/alphatab/model/PercussionMapper'; import { NotationElement, NotationMode } from '@coderline/alphatab/NotationSettings'; import type { ICanvas } from '@coderline/alphatab/platform/ICanvas'; import { Glyph } from '@coderline/alphatab/rendering/glyphs/Glyph'; import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { ElementStyleHelper } from '@coderline/alphatab/rendering/utils/ElementStyleHelper'; -import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; import type { IBoundsLookupWriter } from '@coderline/alphatab/rendering/utils/IBoundsLookupWriter'; /** @@ -22,20 +21,36 @@ export class NoteNumberGlyph extends Glyph { private _trillNoteString: string | null = null; private _trillNoteStringWidth: number = 0; - private _isUnplayable: boolean = false; - public isEmpty: boolean = false; public noteStringWidth: number = 0; /** - * The string (1 = lowest) on which the note is shown. + * The string (1 = lowest) on which the note is shown, 0 until it is placed. + */ + public displayString: number = 0; + /** + * The shown fret, the node for natural harmonics. + */ + public displayFret: number = 0; + /** + * Whether the note is shown on another string than in the model. */ - public displayString: number; + public isMoved: boolean = false; + /** + * Whether no string of the transposed tab can play the note. + */ + public isUnplayable: boolean = false; - public constructor(x: number, y: number, note: Note, displayString: number) { + public constructor(x: number, y: number, note: Note) { super(x, y); this._note = note; - this.displayString = displayString; + } + + public setDisplay(str: number, fret: number, isMoved: boolean, isUnplayable: boolean): void { + this.displayString = str; + this.displayFret = fret; + this.isMoved = isMoved; + this.isUnplayable = isUnplayable; } public get note(): Note { @@ -58,16 +73,8 @@ export class NoteNumberGlyph extends Glyph { const n: Note = this._note; const tr = this.renderer as TabBarRenderer; let fret: number; - let harmonicType = n.harmonicType; - let harmonicValue = n.harmonicValue; if (n.isStringed) { - fret = tr.getDisplayFret(n); - const flags = tr.getDisplayFlags(n); - this._isUnplayable = (flags & TabFingeringSegment.flagUnplayable) !== 0; - if ((flags & TabFingeringSegment.flagAsArtificial) !== 0) { - harmonicType = HarmonicType.Artificial; - harmonicValue = 12; - } + fret = this.displayFret; } else { const articulation = PercussionMapper.getArticulation(n); if (articulation) { @@ -81,7 +88,7 @@ export class NoteNumberGlyph extends Glyph { this._noteString = n.isDead ? 'x' : fret.toString(); if (n.isGhost) { this._noteString = `(${this._noteString})`; - } else if (harmonicType === HarmonicType.Natural) { + } else if (n.harmonicType === HarmonicType.Natural) { // only first decimal char const i: number = this._noteString.indexOf(String.fromCharCode(46)); if (i >= 0) { @@ -99,15 +106,18 @@ export class NoteNumberGlyph extends Glyph { this._noteString = ''; } if (n.isTrill) { - this._trillNoteString = `(${tr.getDisplayTrillFret(n).toString()})`; - } else if (!ModelUtils.isAlmostEqualTo(harmonicValue, 0)) { - switch (harmonicType) { + const staff = n.beat.voice.bar.staff; + const trillFret = + n.trillValue - staff.transpositionPitch - staff.capo - Note.getStringTuning(staff, this.displayString); + this._trillNoteString = `(${trillFret.toString()})`; + } else if (!ModelUtils.isAlmostEqualTo(n.harmonicValue, 0)) { + switch (n.harmonicType) { case HarmonicType.Artificial: case HarmonicType.Pinch: case HarmonicType.Tap: case HarmonicType.Semi: case HarmonicType.Feedback: - let s: string = (fret + harmonicValue).toString(); + let s: string = (fret + n.harmonicValue).toString(); // only first decimal char const i: number = s.indexOf(String.fromCharCode(46)); if (i >= 0) { @@ -183,7 +193,7 @@ export class NoteNumberGlyph extends Glyph { } private _applyColor(canvas: ICanvas): Color | undefined { - return this._isUnplayable + return this.isUnplayable ? ElementStyleHelper.applyNoteWithDefault( canvas, NoteSubElement.GuitarTabFretNumber, diff --git a/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts b/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts index 716610dd53..754dedcce8 100644 --- a/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/StringNumberContainerGlyph.ts @@ -50,7 +50,8 @@ export class StringNumberContainerGlyph extends EffectGlyph { this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.GuitarString0)! * this.renderer.smuflMetrics.tuningGlyphCircleNumberScale; for (const note of this._notes) { // resolved on paint: the tab of the bar is laid out after this staff - const stringValue = stringCount - TabBarRenderer.resolveDisplayString(this.renderer, note); + const tabGlyph = TabBarRenderer.findTabNoteGlyph(this.renderer, note); + const stringValue = stringCount - (tabGlyph !== null ? tabGlyph.displayString : note.string); const symbol = ((MusicFontSymbol.GuitarString1 as number) + stringValue) as MusicFontSymbol; CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x, diff --git a/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts index a7211aac5b..f47a3505e4 100644 --- a/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabBeatGlyph.ts @@ -15,6 +15,7 @@ import { TremoloPickingGlyph } from '@coderline/alphatab/rendering/glyphs/Tremol import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { BeamingHelper } from '@coderline/alphatab/rendering/utils/BeamingHelper'; import type { IBoundsLookupWriter } from '@coderline/alphatab/rendering/utils/IBoundsLookupWriter'; +import { TabFingering } from '@coderline/alphatab/rendering/utils/TabFingering'; /** * @internal @@ -147,13 +148,21 @@ export class TabBeatGlyph extends BeatOnNoteGlyphBase { const tabNoteNumbers = new TabNoteChordGlyph(0, 0, isGrace); this.noteNumbers = tabNoteNumbers; tabNoteNumbers.beat = this.container.beat; + tabNoteNumbers.renderer = this.renderer; for (const note of this.container.beat.notes) { // pitched notes without tab position (e.g. string annotations) have no fret to show if (note.isVisible && (note.isStringed || note.isPercussion)) { - this._createNoteGlyph(note); + const noteNumberGlyph = new NoteNumberGlyph(0, 0, note); + noteNumberGlyph.renderer = this.renderer; + tabNoteNumbers.addNoteGlyph(noteNumberGlyph); } } - tabNoteNumbers.renderer = this.renderer; + TabFingering.assign(tabRenderer, tabNoteNumbers.noteGlyphs); + for (let i = 0; i < tabNoteNumbers.noteGlyphs.length; i++) { + const noteNumberGlyph = tabNoteNumbers.noteGlyphs[i]; + this._layoutNoteGlyph(noteNumberGlyph); + } + tabNoteNumbers.updateStringRange(); } // @@ -230,14 +239,11 @@ export class TabBeatGlyph extends BeatOnNoteGlyphBase { } } - private _createNoteGlyph(n: Note): void { + private _layoutNoteGlyph(noteNumberGlyph: NoteNumberGlyph): void { const tr: TabBarRenderer = this.renderer as TabBarRenderer; - const noteNumberGlyph: NoteNumberGlyph = new NoteNumberGlyph(0, 0, n, tr.getDisplayString(n)); - const l: number = tr.getNoteLine(n); + const l: number = this.renderer.bar.staff.tuning.length - noteNumberGlyph.displayString; noteNumberGlyph.y = tr.getLineY(l); - noteNumberGlyph.renderer = this.renderer; noteNumberGlyph.doLayout(); - this.noteNumbers!.addNoteGlyph(noteNumberGlyph); if (tr.drawsRhythm) { tr.collisionHelper.reserveBeatSlot( this.container.beat, diff --git a/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts b/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts index ccd6b22e58..a43681ed85 100644 --- a/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts +++ b/packages/alphatab/src/rendering/glyphs/TabNoteChordGlyph.ts @@ -7,7 +7,6 @@ import { NoteXPosition, NoteYPosition } from '@coderline/alphatab/rendering/BarR import { DeadSlappedBeatGlyph } from '@coderline/alphatab/rendering/glyphs/DeadSlappedBeatGlyph'; import { Glyph } from '@coderline/alphatab/rendering/glyphs/Glyph'; import type { NoteNumberGlyph } from '@coderline/alphatab/rendering/glyphs/NoteNumberGlyph'; -import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; import { ElementStyleHelper } from '@coderline/alphatab/rendering/utils/ElementStyleHelper'; /** @@ -21,8 +20,6 @@ export class TabNoteChordGlyph extends Glyph { public beat!: Beat; public maxStringNote: Note | null = null; public minStringNote: Note | null = null; - private _maxString: number = 0; - private _minString: number = 0; private _beatEffects: Map | null = null; public noteStringWidth: number = 0; @@ -46,17 +43,21 @@ export class TabNoteChordGlyph extends Glyph { return null; } - /** - * The glyph of the given note, or the glyph shown on its string if the note has none (e.g. a hidden note). - */ - public getNoteGlyph(note: Note): NoteNumberGlyph | null { + public findNoteGlyph(note: Note): NoteNumberGlyph | null { const notes = this._notes; for (let i = notes.length - 1; i >= 0; i--) { if (notes[i].note === note) { return notes[i]; } } - return this.getNoteGlyphForString((this.renderer as TabBarRenderer).getDisplayString(note)); + return null; + } + + /** + * The glyph of the given note, or the glyph shown on its string if the note has none (e.g. a hidden note). + */ + public getNoteGlyph(note: Note): NoteNumberGlyph | null { + return this.findNoteGlyph(note) ?? this.getNoteGlyphForString(note.string); } public get beatEffects(): Map { @@ -198,14 +199,24 @@ export class TabNoteChordGlyph extends Glyph { } else { this._notes.push(noteGlyph); } - const str = noteGlyph.displayString; - if (!this.minStringNote || str < this._minString) { - this.minStringNote = noteGlyph.note; - this._minString = str; - } - if (!this.maxStringNote || str > this._maxString) { - this.maxStringNote = noteGlyph.note; - this._maxString = str; + } + + /** + * Updates {@link minStringNote} and {@link maxStringNote} once the notes are placed on their strings. + */ + public updateStringRange(): void { + let minString = 0; + let maxString = 0; + for (let i = 0; i < this._notes.length; i++) { + const g = this._notes[i]; + if (!this.minStringNote || g.displayString < minString) { + this.minStringNote = g.note; + minString = g.displayString; + } + if (!this.maxStringNote || g.displayString > maxString) { + this.maxStringNote = g.note; + maxString = g.displayString; + } } } diff --git a/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts b/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts index d8928824e7..3ad3e205e5 100644 --- a/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts +++ b/packages/alphatab/src/rendering/layout/VerticalLayoutBase.ts @@ -10,7 +10,7 @@ import { ScoreLayout } from '@coderline/alphatab/rendering/layout/ScoreLayout'; import { RenderFinishedEventArgs } from '@coderline/alphatab/rendering/RenderFinishedEventArgs'; import type { MasterBarsRenderers } from '@coderline/alphatab/rendering/staves/MasterBarsRenderers'; import type { StaffSystem } from '@coderline/alphatab/rendering/staves/StaffSystem'; -import { TabFingeringSolver } from '@coderline/alphatab/rendering/utils/TabFingeringSolver'; +import { TabFingering } from '@coderline/alphatab/rendering/utils/TabFingering'; /** * How the fill loop chose the bars of a pooled system: the system holds the measured master bars @@ -119,7 +119,7 @@ export abstract class VerticalLayoutBase extends ScoreLayout { public override doUpdateForBars(renderHints: RenderHints): boolean { this._reuseViewPort = renderHints.reuseViewport ?? false; // a transposed tab is fingered per segment of linked bars which has to be laid out as a whole - const firstModifiedMasterBar = TabFingeringSolver.firstAffectedBarIndex( + const firstModifiedMasterBar = TabFingering.firstAffectedBarIndex( this.renderer.tracks!, renderHints.firstChangedMasterBar! ); diff --git a/packages/alphatab/src/rendering/utils/TabFingering.ts b/packages/alphatab/src/rendering/utils/TabFingering.ts new file mode 100644 index 0000000000..2d7d721570 --- /dev/null +++ b/packages/alphatab/src/rendering/utils/TabFingering.ts @@ -0,0 +1,280 @@ +import { HarmonicType } from '@coderline/alphatab/model/HarmonicType'; +import { ModelUtils } from '@coderline/alphatab/model/ModelUtils'; +import { Note } from '@coderline/alphatab/model/Note'; +import { SlideInType } from '@coderline/alphatab/model/SlideInType'; +import { SlideOutType } from '@coderline/alphatab/model/SlideOutType'; +import type { Staff } from '@coderline/alphatab/model/Staff'; +import type { Track } from '@coderline/alphatab/model/Track'; +import { VibratoType } from '@coderline/alphatab/model/VibratoType'; +import type { NoteNumberGlyph } from '@coderline/alphatab/rendering/glyphs/NoteNumberGlyph'; +import type { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; + +/** + * Places the notes of a transposed tab on playable strings, beat by beat while the tab is laid out. + * A note keeps its string when its shifted fret is playable there. Tied, slid and hammered notes + * stay on the string of their origin. Other notes take the free string closest to the frets of the beat + * or the previous beat, or keep their string marked as unplayable. + * @internal + */ +export class TabFingering { + private static readonly _maxFret: number = 24; + + // natural harmonic nodes and the semitones they sound above the open string + private static readonly _nodeValues: number[] = [ + 12, 7, 19, 5, 24, 4, 9, 16, 3.2, 2.7, 5.8, 9.6, 14.7, 2.4, 8.2, 17, 21.7 + ]; + private static readonly _nodeIntervals: number[] = [ + 12, 19, 19, 24, 24, 28, 28, 28, 31, 34, 34, 34, 34, 36, 36, 36, 36 + ]; + + public static isActive(staff: Staff): boolean { + return staff.transpositionPitch !== 0 && !staff.isPercussion && staff.tuning.length > 0; + } + + /** + * Sets the displayed string and fret of the note glyphs of one beat. + */ + public static assign(renderer: TabBarRenderer, glyphs: NoteNumberGlyph[]): void { + if (glyphs.length === 0) { + return; + } + const staff = glyphs[0].note.beat.voice.bar.staff; + if (!TabFingering.isActive(staff)) { + for (let i = 0; i < glyphs.length; i++) { + const g = glyphs[i]; + const n = g.note; + g.setDisplay(n.string, TabFingering._modelFret(n), false, false); + } + return; + } + + let usedStrings = 0; + // continuations of ties, slides and hammer-ons/pull-offs follow their origin + for (let i = 0; i < glyphs.length; i++) { + const g = glyphs[i]; + const n = g.note; + const origin = TabFingering._origin(n); + if (origin !== null) { + let str = renderer.getDisplayString(origin) + n.string - origin.string; + if (str < 1 || str > staff.tuning.length) { + str = n.string; + } + TabFingering._place(g, str, n.string); + usedStrings |= 1 << (str - 1); + } + } + // notes playable on their own string keep it + for (let i = 0; i < glyphs.length; i++) { + const g = glyphs[i]; + const n = g.note; + const bit = 1 << (n.string - 1); + if ( + g.displayString === 0 && + (usedStrings & bit) === 0 && + !Number.isNaN(TabFingering._fretOn(n, n.string)) && + TabFingering._chainFits(n, 0) + ) { + TabFingering._place(g, n.string, n.string); + usedStrings |= bit; + } + } + // the remaining notes, highest first, take the free string closest to the hand + while (true) { + let next: NoteNumberGlyph | null = null; + for (let i = 0; i < glyphs.length; i++) { + const g = glyphs[i]; + if (g.displayString === 0 && (next === null || g.note.realValue > next.note.realValue)) { + next = g; + } + } + if (next === null) { + break; + } + const n = next.note; + const hand = TabFingering._handPosition(renderer, glyphs); + let bestString = n.string; + let bestCost = Number.POSITIVE_INFINITY; + for (let str = 1; str <= staff.tuning.length; str++) { + const fret = TabFingering._fretOn(n, str); + if ( + (usedStrings & (1 << (str - 1))) !== 0 || + Number.isNaN(fret) || + !TabFingering._chainFits(n, str - n.string) + ) { + continue; + } + const cost = hand > 0 ? Math.abs(fret - hand) : fret; + if (cost < bestCost) { + bestCost = cost; + bestString = str; + } + } + TabFingering._place(next, bestString, n.string); + usedStrings |= 1 << (bestString - 1); + } + } + + private static _place(g: NoteNumberGlyph, str: number, modelString: number): void { + const fret = TabFingering._fretOn(g.note, str); + if (Number.isNaN(fret)) { + g.setDisplay(str, TabFingering._modelFret(g.note), str !== modelString, true); + } else { + g.setDisplay(str, fret, str !== modelString, false); + } + } + + /** + * The model fret shifted by the transposition, shown for untransposed staves and unplayable notes. + */ + private static _modelFret(n: Note): number { + const shown = TabFingering._isNaturalHarmonic(n) ? n.harmonicValue : n.fret; + return shown - n.beat.voice.bar.staff.transpositionPitch; + } + + private static _isNaturalHarmonic(n: Note): boolean { + return n.harmonicType === HarmonicType.Natural && !ModelUtils.isAlmostEqualTo(n.harmonicValue, 0); + } + + /** + * The fret (natural harmonics: the node) playing the note on the given string, NaN if it cannot be played there. + */ + private static _fretOn(n: Note, str: number): number { + const staff = n.beat.voice.bar.staff; + if (str < 1 || str > staff.tuning.length) { + return Number.NaN; + } + const stringPitch = staff.capo + Note.getStringTuning(staff, str); + if (TabFingering._isNaturalHarmonic(n)) { + const interval = n.realValue - stringPitch; + let node = Number.NaN; + for (let i = 0; i < TabFingering._nodeIntervals.length; i++) { + const value = TabFingering._nodeValues[i]; + if ( + TabFingering._nodeIntervals[i] === interval && + (Number.isNaN(node) || Math.abs(value - n.harmonicValue) < Math.abs(node - n.harmonicValue)) + ) { + node = value; + } + } + return node; + } + const fret = n.realValueWithoutHarmonic - stringPitch; + if (n.isDead) { + return fret; + } + const maxFret = Math.max(TabFingering._maxFret - staff.capo, n.fret); + if (fret < 0 || fret > maxFret || (fret === 0 && TabFingering._needsFrettedString(n))) { + return Number.NaN; + } + if (n.isTrill) { + const trillFret = n.trillValue - staff.transpositionPitch - stringPitch; + if (trillFret < 0 || trillFret > maxFret) { + return Number.NaN; + } + } + return fret; + } + + private static _needsFrettedString(n: Note): boolean { + return ( + n.hasBend || + n.isContinuedBend || + n.vibrato !== VibratoType.None || + n.isLeftHandTapped || + n.slideInType !== SlideInType.None || + n.slideOutType === SlideOutType.Shift || + n.slideOutType === SlideOutType.Legato || + n.slideOutType === SlideOutType.OutUp || + n.slideOutType === SlideOutType.OutDown || + n.slideOrigin !== null || + // a hammer-on cannot end on an open string, a pull-off can + (n.hammerPullOrigin !== null && n.hammerPullOrigin.realValue < n.realValue) + ); + } + + /** + * The note which this note continues on the same string. + */ + private static _origin(n: Note): Note | null { + if (n.isTieDestination && n.tieOrigin !== null) { + return n.tieOrigin; + } + return n.slideOrigin ?? n.hammerPullOrigin; + } + + /** + * Whether all notes continuing the given one are playable when moved by the given number of strings. + */ + private static _chainFits(n: Note, stringDelta: number): boolean { + const tie = n.tieDestination; + const slide = + n.slideOutType === SlideOutType.Shift || n.slideOutType === SlideOutType.Legato ? n.slideTarget : null; + const hammer = n.isHammerPullOrigin ? n.hammerPullDestination : null; + return ( + TabFingering._fits(tie, stringDelta) && + TabFingering._fits(slide, stringDelta) && + TabFingering._fits(hammer, stringDelta) + ); + } + + private static _fits(n: Note | null, stringDelta: number): boolean { + return ( + n === null || + (!Number.isNaN(TabFingering._fretOn(n, n.string + stringDelta)) && TabFingering._chainFits(n, stringDelta)) + ); + } + + /** + * The average fret of the notes placed in this beat, or of the previous beat in the voice, 0 if unknown. + */ + private static _handPosition(renderer: TabBarRenderer, glyphs: NoteNumberGlyph[]): number { + let sum = 0; + let count = 0; + for (let i = 0; i < glyphs.length; i++) { + const g = glyphs[i]; + if (g.displayString > 0 && !g.note.isDead && g.displayFret > 0) { + sum += g.displayFret; + count++; + } + } + const previous = glyphs[0].note.beat.previousBeat; + if (count === 0 && previous !== null) { + for (let i = 0; i < previous.notes.length; i++) { + const p = previous.notes[i]; + const fret = renderer.getDisplayFret(p); + if (p.isStringed && !p.isDead && fret > 0) { + sum += fret; + count++; + } + } + } + return count > 0 ? sum / count : 0; + } + + /** + * The first bar whose tab may change when the given bar changes: notes continued in it are + * placed together with their origin. + */ + public static firstAffectedBarIndex(tracks: Track[], barIndex: number): number { + let first = barIndex; + for (const track of tracks) { + for (const staff of track.staves) { + if (!staff.showTablature || !TabFingering.isActive(staff) || barIndex >= staff.bars.length) { + continue; + } + for (const voice of staff.bars[barIndex].voices) { + for (const beat of voice.beats) { + for (const note of beat.notes) { + let origin = TabFingering._origin(note); + while (origin !== null) { + first = Math.min(first, origin.beat.voice.bar.index); + origin = TabFingering._origin(origin); + } + } + } + } + } + } + return first; + } +} diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSegment.ts b/packages/alphatab/src/rendering/utils/TabFingeringSegment.ts deleted file mode 100644 index 5e2ef85e7a..0000000000 --- a/packages/alphatab/src/rendering/utils/TabFingeringSegment.ts +++ /dev/null @@ -1,90 +0,0 @@ -import type { Note } from '@coderline/alphatab/model/Note'; - -/** - * The display fingering (string, fret, harmonic node) of all notes of a run of bars of one staff, - * as decided by {@link TabFingeringSolver}. Values are only meaningful for stringed notes of the bars - * from {@link firstBarIndex} to {@link lastBarIndex}. - * @internal - */ -export class TabFingeringSegment { - /** - * The note is displayed on another string than in the model. - */ - public static readonly flagMoved: number = 1; - /** - * No position on the tuning can play the note, it keeps its model string with an out of range fret. - */ - public static readonly flagUnplayable: number = 2; - /** - * A natural harmonic without a matching node, displayed as artificial harmonic an octave above the fret. - */ - public static readonly flagAsArtificial: number = 4; - - public readonly firstBarIndex: number; - public readonly lastBarIndex: number; - - private readonly _barVoiceBase: Int32Array; - private readonly _voiceBeatBase: Int32Array; - private readonly _beatNoteBase: Int32Array; - private readonly _strings: Uint8Array; - private readonly _frets: Int16Array; - private readonly _nodes: Int8Array; - private readonly _flags: Uint8Array; - - public constructor( - firstBarIndex: number, - lastBarIndex: number, - barVoiceBase: Int32Array, - voiceBeatBase: Int32Array, - beatNoteBase: Int32Array, - noteCount: number - ) { - this.firstBarIndex = firstBarIndex; - this.lastBarIndex = lastBarIndex; - this._barVoiceBase = barVoiceBase; - this._voiceBeatBase = voiceBeatBase; - this._beatNoteBase = beatNoteBase; - this._strings = new Uint8Array(noteCount); - this._frets = new Int16Array(noteCount); - this._nodes = new Int8Array(noteCount); - this._nodes.fill(-1); - this._flags = new Uint8Array(noteCount); - } - - public covers(barIndex: number): boolean { - return barIndex >= this.firstBarIndex && barIndex <= this.lastBarIndex; - } - - public noteIndex(note: Note): number { - const beat = note.beat; - const voice = beat.voice; - const voiceIndex = this._barVoiceBase[voice.bar.index - this.firstBarIndex] + voice.index; - return this._beatNoteBase[this._voiceBeatBase[voiceIndex] + beat.index] + note.index; - } - - public getString(note: Note): number { - return this._strings[this.noteIndex(note)]; - } - - public getFret(note: Note): number { - return this._frets[this.noteIndex(note)]; - } - - /** - * The index into {@link TabFingeringSolver.naturalNodeValues} for natural harmonics, -1 otherwise. - */ - public getNode(note: Note): number { - return this._nodes[this.noteIndex(note)]; - } - - public getFlags(note: Note): number { - return this._flags[this.noteIndex(note)]; - } - - public set(index: number, str: number, fret: number, node: number, flags: number): void { - this._strings[index] = str; - this._frets[index] = fret; - this._nodes[index] = node; - this._flags[index] = flags; - } -} diff --git a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts b/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts deleted file mode 100644 index 31f632e5ea..0000000000 --- a/packages/alphatab/src/rendering/utils/TabFingeringSolver.ts +++ /dev/null @@ -1,1221 +0,0 @@ -import type { Beat } from '@coderline/alphatab/model/Beat'; -import { GraceType } from '@coderline/alphatab/model/GraceType'; -import { HarmonicType } from '@coderline/alphatab/model/HarmonicType'; -import { ModelUtils } from '@coderline/alphatab/model/ModelUtils'; -import type { Note } from '@coderline/alphatab/model/Note'; -import { SlideInType } from '@coderline/alphatab/model/SlideInType'; -import { SlideOutType } from '@coderline/alphatab/model/SlideOutType'; -import type { Staff } from '@coderline/alphatab/model/Staff'; -import type { Track } from '@coderline/alphatab/model/Track'; -import { VibratoType } from '@coderline/alphatab/model/VibratoType'; -import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; - -/** - * Cost weights for {@link TabFingeringSolver}. Position weights follow {@link FingeringOptions}. - * @internal - */ -export class TabFingeringOptions { - /** - * The highest fret counted from the nut; notes using a higher fret in the model raise the limit for themselves. - */ - public defaultMaxFret: number = 24; - public maxSpan: number = 5; - public spanWeight: number = 0.25; - /** Per fret of span beyond {@link maxSpan}. */ - public overSpanPenalty: number = 10; - public highFretThreshold: number = 12; - public highFretPenaltyWeight: number = 0.5; - /** Negative = prefer open strings. */ - public openStringBonus: number = -1; - /** Cost of placing a note on a string which is still sounding from an earlier beat. */ - public occupancyPenalty: number = 8; - public asArtificialPenalty: number = 20; - public handMovementWeight: number = 1; - /** The states kept per time slice, at most 255. */ - public beamWidth: number = 16; - public maxLeavesPerState: number = 256; -} - -/** - * Decides on which string and fret tab notes are displayed when the staff is transposed. - * Works purely on the model and never modifies it. - * - * Notes keep their model string whenever the transposed fret is playable there. Otherwise the - * bars connected by ties, slides and hammer-ons/pull-offs are re-fingered together, preferring - * (in this order) fewer unplayable notes, fewer notes moved to another string and a smaller - * hand movement and stretch. - * @internal - */ -export class TabFingeringSolver { - /** - * The harmonic values of the natural harmonic nodes, as produced by - * {@link ModelUtils.deltaFretToHarmonicValue} plus the extra nodes known by {@link ModelUtils.harmonicValueToPitch}. - */ - public static readonly naturalNodeValues: number[] = [ - 12, 7, 19, 5, 24, 4, 9, 16, 3.2, 2.7, 5.8, 9.6, 14.7, 2.4, 8.2, 17, 21.7 - ]; - - // the semitones above the open string for each entry of naturalNodeValues - private static readonly _naturalNodeIntervals: number[] = [ - 12, 19, 19, 24, 24, 28, 28, 28, 31, 34, 34, 34, 34, 36, 36, 36, 36 - ]; - - // Note.nextNoteOnSameLine and findHammerPullDestination search up to 3 bars ahead - private static readonly _maxLinkBarDistance: number = 4; - - private static readonly _defaultOptions: TabFingeringOptions = new TabFingeringOptions(); - - /** - * Whether the tab of the given staff is displayed with a fingering differing from the model. - */ - public static isActive(staff: Staff): boolean { - return staff.transpositionPitch !== 0 && !staff.isPercussion && staff.tuning.length > 0; - } - - public static isNaturalHarmonic(note: Note): boolean { - return note.harmonicType === HarmonicType.Natural && !ModelUtils.isAlmostEqualTo(note.harmonicValue, 0); - } - - /** - * Finds the natural harmonic node sounding the given interval above the open string. - * @param interval The semitones above the open string. - * @param preferredValue The harmonic value to stay closest to. - * @returns The index into {@link naturalNodeValues} or -1 if no node sounds this interval. - */ - public static findNaturalNode(interval: number, preferredValue: number): number { - let best = -1; - let bestDistance = 0; - const intervals = TabFingeringSolver._naturalNodeIntervals; - const values = TabFingeringSolver.naturalNodeValues; - for (let i = 0; i < intervals.length; i++) { - if (intervals[i] === interval) { - const distance = Math.abs(values[i] - preferredValue); - if (best === -1 || distance < bestDistance) { - best = i; - bestDistance = distance; - } - } - } - return best; - } - - /** - * The node of a natural harmonic which stays on its model string. - */ - public static findNaturalNodeOnModelString(note: Note): number { - const staff = note.beat.voice.bar.staff; - return TabFingeringSolver.findNaturalNode( - ModelUtils.harmonicValueToPitch(note.harmonicValue) - staff.transpositionPitch, - note.harmonicValue - ); - } - - /** - * Whether no note before the given bar is linked to a note in or after it. - */ - public static isSegmentStart(staff: Staff, barIndex: number): boolean { - const firstChecked = Math.max(0, barIndex - TabFingeringSolver._maxLinkBarDistance); - for (let b = barIndex - 1; b >= firstChecked; b--) { - for (let v = 0; v < staff.bars[b].voices.length; v++) { - const voice = staff.bars[b].voices[v]; - for (let k = 0; k < voice.beats.length; k++) { - const beat = voice.beats[k]; - for (let n = 0; n < beat.notes.length; n++) { - const note = beat.notes[n]; - for (let kind = 0; kind < 3; kind++) { - const target = TabFingeringSolver.nextLinked(note, kind); - if (target !== null && target.beat.voice.bar.index >= barIndex) { - return false; - } - } - } - } - } - } - return true; - } - - /** - * The first bar of the segment containing the given bar. - */ - public static segmentStart(staff: Staff, barIndex: number): number { - let b = barIndex; - while (b > 0 && !TabFingeringSolver.isSegmentStart(staff, b)) { - b--; - } - return b; - } - - /** - * The first bar whose tab fingering may change when the given bar changes, considering the transposed tabs of all tracks. - */ - public static firstAffectedBarIndex(tracks: Track[], barIndex: number): number { - let first = barIndex; - for (const track of tracks) { - for (const staff of track.staves) { - if (staff.showTablature && TabFingeringSolver.isActive(staff) && barIndex < staff.bars.length) { - first = Math.min(first, TabFingeringSolver.segmentStart(staff, barIndex)); - } - } - } - return first; - } - - /** - * The last bar of the segment starting at the given bar. - */ - public static segmentEnd(staff: Staff, firstBarIndex: number): number { - let last = firstBarIndex; - let scanned = firstBarIndex; - while (scanned <= last && scanned < staff.bars.length) { - for (let v = 0; v < staff.bars[scanned].voices.length; v++) { - const voice = staff.bars[scanned].voices[v]; - for (let k = 0; k < voice.beats.length; k++) { - const beat = voice.beats[k]; - for (let n = 0; n < beat.notes.length; n++) { - const note = beat.notes[n]; - for (let kind = 0; kind < 3; kind++) { - const target = TabFingeringSolver.nextLinked(note, kind); - if (target !== null && target.beat.voice.bar.index > last) { - last = target.beat.voice.bar.index; - } - } - } - } - } - scanned++; - } - return last; - } - - /** - * Solves the display fingering of the given bars, which must form a segment. - * @returns The fingering or null if all notes keep their model string and fret shifted by the transposition. - */ - public static solve( - staff: Staff, - firstBarIndex: number, - lastBarIndex: number, - options?: TabFingeringOptions - ): TabFingeringSegment | null { - const resolvedOptions = options ?? TabFingeringSolver._defaultOptions; - if (TabFingeringRun.isIdentity(staff, firstBarIndex, lastBarIndex, resolvedOptions)) { - return null; - } - return new TabFingeringRun(staff, firstBarIndex, lastBarIndex, resolvedOptions).solve(); - } - - /** - * The note which has to stay on the same string as the given one: 0 = tie, 1 = slide, 2 = hammer-on/pull-off. - */ - public static nextLinked(note: Note, kind: number): Note | null { - switch (kind) { - case 0: - return note.tieDestination; - case 1: - return note.slideOutType === SlideOutType.Shift || note.slideOutType === SlideOutType.Legato - ? note.slideTarget - : null; - case 2: - return note.isHammerPullOrigin ? note.hammerPullDestination : null; - } - return null; - } - - public static previousLinked(note: Note, kind: number): Note | null { - switch (kind) { - case 0: - return note.isTieDestination ? note.tieOrigin : null; - case 1: - return note.slideOrigin; - case 2: - return note.hammerPullOrigin; - } - return null; - } -} - -/** - * The state of one {@link TabFingeringSolver.solve} call. - * - * Notes linked by ties, slides and hammer-ons/pull-offs form a group which moves as a whole by a - * string delta, keeping the string offsets of the model. The beats of all voices are merged into - * time slices and a beam search over the slices picks one delta per group. - * @internal - */ -export class TabFingeringRun { - private static readonly _kindSkip: number = 0; - private static readonly _kindNormal: number = 1; - private static readonly _kindDead: number = 2; - private static readonly _kindNatural: number = 3; - - private static readonly _graceRankMain: number = 1000; - private static readonly _ticksPerQuarter: number = 960; - - private readonly _staff: Staff; - private readonly _firstBarIndex: number; - private readonly _lastBarIndex: number; - private readonly _options: TabFingeringOptions; - private readonly _capo: number; - private readonly _tuning: number[]; - private readonly _stringCount: number; - - private _barVoiceBase!: Int32Array; - private _voiceBeatBase!: Int32Array; - private _beatNoteBase!: Int32Array; - private _notes: Note[] = []; - - private _kind!: Uint8Array; - private _target!: Int32Array; - private _originalString!: Int32Array; - private _maxFret!: Int32Array; - private _noOpen!: Uint8Array; - private _trill!: Int32Array; - private _group!: Int32Array; - private _slice!: Int32Array; - private _sustainEnd!: Int32Array; - - private _groupCount: number = 0; - private _groupFirst: number[] = []; - private _groupLast: number[] = []; - private _groupOptionBase: number[] = []; - private _groupOptions: number[] = []; - - private _sliceTick: number[] = []; - private _sliceNoteBase: number[] = []; - private _sliceNotes: number[] = []; - private _soundBase: number[] = []; - private _soundNotes: number[] = []; - private _activeBase: number[] = []; - private _activeGroups: number[] = []; - - // results of _evaluate - private _evalFret: number = 0; - private _evalNode: number = -1; - private _evalFlags: number = 0; - - public constructor(staff: Staff, firstBarIndex: number, lastBarIndex: number, options: TabFingeringOptions) { - this._staff = staff; - this._firstBarIndex = firstBarIndex; - this._lastBarIndex = lastBarIndex; - this._options = options; - this._capo = staff.capo; - this._tuning = staff.tuning; - this._stringCount = staff.tuning.length; - } - - /** - * Solves the bars, which must not be playable as they are (see {@link isIdentity}). - */ - public solve(): TabFingeringSegment { - this._collectNotes(); - - this._buildGroups(); - this._buildSlices(); - this._buildGroupSpans(); - const groupDelta = this._search(); - - const segment = new TabFingeringSegment( - this._firstBarIndex, - this._lastBarIndex, - this._barVoiceBase, - this._voiceBeatBase, - this._beatNoteBase, - this._notes.length - ); - for (let i = 0; i < this._notes.length; i++) { - if (this._kind[i] === TabFingeringRun._kindSkip) { - continue; - } - const delta = groupDelta[this._group[i]]; - const str = this._originalString[i] + delta; - const valid = this._evaluate(i, str); - let flags = this._evalFlags; - if (delta !== 0) { - flags |= TabFingeringSegment.flagMoved; - } - if (!valid) { - flags |= TabFingeringSegment.flagUnplayable; - } - segment.set(i, str, this._evalFret, this._evalNode, flags); - } - return segment; - } - - private _collectNotes(): void { - const bars = this._staff.bars; - let voiceCount = 0; - let beatCount = 0; - for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { - for (let v = 0; v < bars[b].voices.length; v++) { - const voice = bars[b].voices[v]; - voiceCount++; - beatCount += voice.beats.length; - } - } - - this._barVoiceBase = new Int32Array(this._lastBarIndex - this._firstBarIndex + 1); - this._voiceBeatBase = new Int32Array(voiceCount); - this._beatNoteBase = new Int32Array(beatCount); - - const notes = this._notes; - let voiceIndex = 0; - let beatIndex = 0; - for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { - this._barVoiceBase[b - this._firstBarIndex] = voiceIndex; - for (let v = 0; v < bars[b].voices.length; v++) { - const voice = bars[b].voices[v]; - this._voiceBeatBase[voiceIndex] = beatIndex; - voiceIndex++; - for (let k = 0; k < voice.beats.length; k++) { - const beat = voice.beats[k]; - this._beatNoteBase[beatIndex] = notes.length; - beatIndex++; - for (let n = 0; n < beat.notes.length; n++) { - const note = beat.notes[n]; - notes.push(note); - } - } - } - } - - const count = notes.length; - this._kind = new Uint8Array(count); - this._target = new Int32Array(count); - this._originalString = new Int32Array(count); - this._maxFret = new Int32Array(count); - this._noOpen = new Uint8Array(count); - this._trill = new Int32Array(count); - this._group = new Int32Array(count); - this._slice = new Int32Array(count); - this._sustainEnd = new Int32Array(count); - - const transpositionPitch = this._staff.transpositionPitch; - for (let i = 0; i < count; i++) { - const note = notes[i]; - this._group[i] = -1; - this._slice[i] = -1; - if (!note.isStringed || note.string < 1 || note.string > this._stringCount) { - this._kind[i] = TabFingeringRun._kindSkip; - continue; - } - - if (note.isDead) { - this._kind[i] = TabFingeringRun._kindDead; - this._target[i] = note.realValueWithoutHarmonic; - } else if (TabFingeringSolver.isNaturalHarmonic(note)) { - this._kind[i] = TabFingeringRun._kindNatural; - this._target[i] = note.realValue; - } else { - this._kind[i] = TabFingeringRun._kindNormal; - this._target[i] = note.realValueWithoutHarmonic; - } - this._originalString[i] = note.string; - this._maxFret[i] = Math.max(this._options.defaultMaxFret - this._capo, note.fret); - this._noOpen[i] = TabFingeringRun._needsFrettedString(note) ? 1 : 0; - this._trill[i] = note.isTrill ? note.trillValue - transpositionPitch : -1; - } - } - - private static _needsFrettedString(note: Note): boolean { - if (note.hasBend || note.isContinuedBend || note.vibrato !== VibratoType.None || note.isLeftHandTapped) { - return true; - } - if (note.slideInType === SlideInType.IntoFromBelow || note.slideInType === SlideInType.IntoFromAbove) { - return true; - } - switch (note.slideOutType) { - case SlideOutType.Shift: - case SlideOutType.Legato: - case SlideOutType.OutUp: - case SlideOutType.OutDown: - return true; - } - if (note.slideOrigin !== null) { - return true; - } - // a hammer-on cannot end on an open string, a pull-off can - const hammerPullOrigin = note.hammerPullOrigin; - if (hammerPullOrigin !== null && hammerPullOrigin.realValue < note.realValue) { - return true; - } - return false; - } - - private _stringPitch(str: number): number { - return this._capo + this._tuning[this._stringCount - str]; - } - - /** - * Evaluates the note on the given string into {@link _evalFret}, {@link _evalNode} and {@link _evalFlags}. - * @returns Whether the note can be played there. - */ - private _evaluate(i: number, str: number): boolean { - const stringPitch = this._stringPitch(str); - const target = this._target[i]; - const maxFret = this._maxFret[i]; - this._evalNode = -1; - this._evalFlags = 0; - switch (this._kind[i]) { - case TabFingeringRun._kindDead: - this._evalFret = target - stringPitch; - return true; - case TabFingeringRun._kindNatural: { - const node = TabFingeringSolver.findNaturalNode(target - stringPitch, this._notes[i].harmonicValue); - if (node >= 0) { - this._evalFret = 0; - this._evalNode = node; - return true; - } - const baseFret = target - 12 - stringPitch; - this._evalFret = baseFret; - this._evalFlags = TabFingeringSegment.flagAsArtificial; - return baseFret >= 0 && baseFret <= maxFret; - } - } - - const fret = target - stringPitch; - this._evalFret = fret; - const trill = this._trill[i]; - return TabFingeringRun._isPlayableFret(fret, maxFret, this._noOpen[i] !== 0, trill >= 0, trill - stringPitch); - } - - private static _isPlayableFret( - fret: number, - maxFret: number, - needsFrettedString: boolean, - hasTrill: boolean, - trillFret: number - ): boolean { - if (fret < 0 || fret > maxFret || (fret === 0 && needsFrettedString)) { - return false; - } - return !hasTrill || (trillFret >= 0 && trillFret <= maxFret); - } - - /** - * Whether every note is playable on its model string with the fret shifted by the transposition, - * natural harmonics on a node of their string. Reads the model directly to allocate nothing for - * the common case. - */ - public static isIdentity( - staff: Staff, - firstBarIndex: number, - lastBarIndex: number, - options: TabFingeringOptions - ): boolean { - const transpositionPitch = staff.transpositionPitch; - const stringCount = staff.tuning.length; - for (let b = firstBarIndex; b <= lastBarIndex; b++) { - for (let v = 0; v < staff.bars[b].voices.length; v++) { - const voice = staff.bars[b].voices[v]; - for (let k = 0; k < voice.beats.length; k++) { - const beat = voice.beats[k]; - for (let n = 0; n < beat.notes.length; n++) { - const note = beat.notes[n]; - if (!note.isStringed || note.string < 1 || note.string > stringCount || note.isDead) { - continue; - } - if (TabFingeringSolver.isNaturalHarmonic(note)) { - if (TabFingeringSolver.findNaturalNodeOnModelString(note) < 0) { - return false; - } - continue; - } - const maxFret = Math.max(options.defaultMaxFret - staff.capo, note.fret); - if ( - !TabFingeringRun._isPlayableFret( - note.fret - transpositionPitch, - maxFret, - TabFingeringRun._needsFrettedString(note), - note.isTrill, - note.isTrill ? note.trillFret - transpositionPitch : 0 - ) - ) { - return false; - } - } - } - } - } - return true; - } - - private _indexOf(note: Note): number { - const bar = note.beat.voice.bar; - if (bar.staff !== this._staff || bar.index < this._firstBarIndex || bar.index > this._lastBarIndex) { - return -1; - } - const voiceIndex = this._barVoiceBase[bar.index - this._firstBarIndex] + note.beat.voice.index; - return this._beatNoteBase[this._voiceBeatBase[voiceIndex] + note.beat.index] + note.index; - } - - private _buildGroups(): void { - const count = this._notes.length; - const stack: number[] = []; - const groupMembers: number[] = []; - const groupMemberBase: number[] = []; - for (let i = 0; i < count; i++) { - if (this._kind[i] === TabFingeringRun._kindSkip || this._group[i] >= 0) { - continue; - } - const g = this._groupCount; - this._groupCount++; - groupMemberBase.push(groupMembers.length); - this._group[i] = g; - stack.push(i); - while (stack.length > 0) { - const current = stack.pop()!; - groupMembers.push(current); - const note = this._notes[current]; - for (let kind = 0; kind < 3; kind++) { - for (let direction = 0; direction < 2; direction++) { - const linked = - direction === 0 - ? TabFingeringSolver.nextLinked(note, kind) - : TabFingeringSolver.previousLinked(note, kind); - if (linked === null) { - continue; - } - const linkedIndex = this._indexOf(linked); - if ( - linkedIndex >= 0 && - this._kind[linkedIndex] !== TabFingeringRun._kindSkip && - this._group[linkedIndex] < 0 - ) { - this._group[linkedIndex] = g; - stack.push(linkedIndex); - } - } - } - } - } - groupMemberBase.push(groupMembers.length); - - // the string deltas keeping all members on the instrument, playable ones first - const options = this._groupOptions; - const optionFret: number[] = []; - for (let g = 0; g < this._groupCount; g++) { - this._groupOptionBase.push(options.length); - const memberStart = groupMemberBase[g]; - const memberEnd = groupMemberBase[g + 1]; - let minString = this._stringCount; - let maxString = 1; - let head = groupMembers[memberStart]; - for (let m = memberStart; m < memberEnd; m++) { - const member = groupMembers[m]; - minString = Math.min(minString, this._originalString[member]); - maxString = Math.max(maxString, this._originalString[member]); - if (member < head) { - head = member; - } - } - - const optionStart = options.length; - let hasZero = false; - for (let delta = 1 - minString; delta <= this._stringCount - maxString; delta++) { - let valid = true; - for (let m = memberStart; m < memberEnd && valid; m++) { - const member = groupMembers[m]; - valid = this._evaluate(member, this._originalString[member] + delta); - } - if (!valid) { - continue; - } - this._evaluate(head, this._originalString[head] + delta); - const headFret = this._evalFret; - // order: model string, then lower fret, then lower string - let insertAt = options.length; - if (delta === 0) { - insertAt = optionStart; - hasZero = true; - } else { - while (insertAt > optionStart) { - const previousDelta = options[insertAt - 1]; - const previousFret = optionFret[insertAt - 1]; - if ( - previousDelta === 0 || - previousFret < headFret || - (previousFret === headFret && previousDelta < delta) - ) { - break; - } - insertAt--; - } - } - options.push(delta); - optionFret.push(headFret); - for (let m = options.length - 1; m > insertAt; m--) { - options[m] = options[m - 1]; - optionFret[m] = optionFret[m - 1]; - } - options[insertAt] = delta; - optionFret[insertAt] = headFret; - } - if (!hasZero) { - // last resort: keep the model strings, unplayable notes are flagged - options.push(0); - optionFret.push(0); - } - } - this._groupOptionBase.push(options.length); - } - - private _hasSolvedNotes(beat: Beat): boolean { - const notes = beat.notes; - for (let n = 0; n < notes.length; n++) { - if (this._kind[this._indexOf(notes[n])] !== TabFingeringRun._kindSkip) { - return true; - } - } - return false; - } - - private static _graceRank(beat: Beat): number { - return beat.graceType === GraceType.None ? TabFingeringRun._graceRankMain : beat.graceIndex; - } - - private static _compareBeats(a: Beat, b: Beat): number { - if (a.voice.bar.index !== b.voice.bar.index) { - return a.voice.bar.index - b.voice.bar.index; - } - if (a.displayStart !== b.displayStart) { - return a.displayStart - b.displayStart; - } - const rankA = TabFingeringRun._graceRank(a); - const rankB = TabFingeringRun._graceRank(b); - if (rankA !== rankB) { - return rankA - rankB; - } - if (a.voice.index !== b.voice.index) { - return a.voice.index - b.voice.index; - } - return a.index - b.index; - } - - private _buildSlices(): void { - const bars = this._staff.bars; - const endTick: number[] = []; - const sliceTick = this._sliceTick; - let previous: Beat | null = null; - let voicePosition = new Int32Array(4); - for (let b = this._firstBarIndex; b <= this._lastBarIndex; b++) { - const voices = bars[b].voices; - if (voicePosition.length < voices.length) { - voicePosition = new Int32Array(voices.length); - } - voicePosition.fill(0); - // merge the voices, each of them is in slice order already - while (true) { - let beat: Beat | null = null; - let beatVoice = -1; - for (let v = 0; v < voices.length; v++) { - const voiceBeats = voices[v].beats; - while ( - voicePosition[v] < voiceBeats.length && - !this._hasSolvedNotes(voiceBeats[voicePosition[v]]) - ) { - voicePosition[v]++; - } - if (voicePosition[v] < voiceBeats.length) { - const candidate = voiceBeats[voicePosition[v]]; - if (beat === null || TabFingeringRun._compareBeats(candidate, beat) < 0) { - beat = candidate; - beatVoice = v; - } - } - } - if (beat === null) { - break; - } - voicePosition[beatVoice]++; - - if ( - previous === null || - previous.voice.bar.index !== beat.voice.bar.index || - previous.displayStart !== beat.displayStart || - TabFingeringRun._graceRank(previous) !== TabFingeringRun._graceRank(beat) - ) { - this._sliceNoteBase.push(this._sliceNotes.length); - sliceTick.push(beat.absoluteDisplayStart); - } - previous = beat; - const slice = sliceTick.length - 1; - const notes = beat.notes; - for (let n = 0; n < notes.length; n++) { - const note = notes[n]; - const i = this._indexOf(note); - if (this._kind[i] === TabFingeringRun._kindSkip) { - continue; - } - this._slice[i] = slice; - this._sliceNotes.push(i); - let end = beat.absoluteDisplayStart + beat.displayDuration; - const letRingDestination = note.isLetRing ? note.letRingDestination : null; - if (letRingDestination !== null) { - const destinationBeat = letRingDestination.beat; - end = Math.max(end, destinationBeat.absoluteDisplayStart + destinationBeat.displayDuration); - } - endTick.push(end); - } - } - } - this._sliceNoteBase.push(this._sliceNotes.length); - - // notes still sounding in later slices - const sliceCount = sliceTick.length; - const soundCount: number[] = new Array(sliceCount).fill(0); - for (let k = 0; k < this._sliceNotes.length; k++) { - const i = this._sliceNotes[k]; - let last = this._slice[i]; - while (last + 1 < sliceCount && sliceTick[last + 1] < endTick[k]) { - last++; - soundCount[last]++; - } - this._sustainEnd[i] = last; - } - this._fillBuckets(soundCount, this._soundBase); - const soundFill: number[] = this._soundBase.slice(0, sliceCount); - for (let s = 0; s < this._soundBase[sliceCount]; s++) { - this._soundNotes.push(0); - } - for (let k = 0; k < this._sliceNotes.length; k++) { - const i = this._sliceNotes[k]; - for (let t = this._slice[i] + 1; t <= this._sustainEnd[i]; t++) { - this._soundNotes[soundFill[t]] = i; - soundFill[t]++; - } - } - } - - private _fillBuckets(counts: number[], base: number[]): void { - let sum = 0; - for (let i = 0; i < counts.length; i++) { - base.push(sum); - sum += counts[i]; - } - base.push(sum); - } - - private _buildGroupSpans(): void { - const groupCount = this._groupCount; - for (let g = 0; g < groupCount; g++) { - this._groupFirst.push(-1); - this._groupLast.push(-1); - } - for (let i = 0; i < this._notes.length; i++) { - const g = this._group[i]; - if (g < 0 || this._slice[i] < 0) { - continue; - } - if (this._groupFirst[g] < 0 || this._slice[i] < this._groupFirst[g]) { - this._groupFirst[g] = this._slice[i]; - } - if (this._sustainEnd[i] > this._groupLast[g]) { - this._groupLast[g] = this._sustainEnd[i]; - } - } - - const sliceCount = this._sliceTick.length; - const activeCount: number[] = new Array(sliceCount).fill(0); - for (let g = 0; g < groupCount; g++) { - for (let t = this._groupFirst[g]; t >= 0 && t <= this._groupLast[g]; t++) { - activeCount[t]++; - } - } - this._fillBuckets(activeCount, this._activeBase); - const activeFill: number[] = this._activeBase.slice(0, sliceCount); - for (let s = 0; s < this._activeBase[sliceCount]; s++) { - this._activeGroups.push(0); - } - for (let g = 0; g < groupCount; g++) { - for (let t = this._groupFirst[g]; t >= 0 && t <= this._groupLast[g]; t++) { - this._activeGroups[activeFill[t]] = g; - activeFill[t]++; - } - } - } - - /** - * Beam search over the slices, each state holding the string delta of every group active in its slice. - * Only the states of the previous slice are kept, plus per slice the back pointers and the deltas of the - * groups starting there to follow the best path back. - * @returns The string delta per group. - */ - private _search(): Int32Array { - const options = this._options; - // back pointers are stored as bytes - const beamWidth = Math.min(options.beamWidth, 255); - const sliceCount = this._sliceTick.length; - const groupCount = this._groupCount; - const activeBase = this._activeBase; - const activeGroups = this._activeGroups; - const groupFirst = this._groupFirst; - const groupLast = this._groupLast; - - let maxActive = 1; - for (let t = 0; t < sliceCount; t++) { - maxActive = Math.max(maxActive, activeBase[t + 1] - activeBase[t]); - } - - // groups starting per slice, in the order of the active groups - const newGroupBase = new Int32Array(sliceCount + 1); - for (let g = 0; g < groupCount; g++) { - newGroupBase[groupFirst[g] + 1]++; - } - for (let t = 0; t < sliceCount; t++) { - newGroupBase[t + 1] += newGroupBase[t]; - } - const newGroupIds = new Int32Array(groupCount); - const newGroupPositions = new Int32Array(groupCount); - for (let t = 0; t < sliceCount; t++) { - let n = newGroupBase[t]; - for (let a = activeBase[t]; a < activeBase[t + 1]; a++) { - const g = activeGroups[a]; - if (groupFirst[g] === t) { - newGroupIds[n] = g; - newGroupPositions[n] = a - activeBase[t]; - n++; - } - } - } - - // the sorted states of the previous slice - const stateUnplayable = new Int32Array(beamWidth); - const stateMoved = new Int32Array(beamWidth); - const stateRest: number[] = new Array(beamWidth).fill(0); - const stateCenter: number[] = new Array(beamWidth).fill(0); - const stateDeltas = new Int8Array(beamWidth * maxActive); - let stateCount = 0; - - // the unsorted candidates of the current slice, the last slot holds the candidate being scored - // (costs are compared by slot, passing doubles between functions would box them) - const scored = beamWidth; - const candidateUnplayable = new Int32Array(beamWidth + 1); - const candidateMoved = new Int32Array(beamWidth + 1); - const candidateRest: number[] = new Array(beamWidth + 1).fill(0); - const candidateCenter: number[] = new Array(beamWidth + 1).fill(0); - const candidateBack = new Int32Array(beamWidth); - const candidateSequence = new Int32Array(beamWidth + 1); - const scores = this._scores; - const candidateDeltas = new Int8Array(beamWidth * maxActive); - const candidateCommitted = new Uint8Array(beamWidth); - - // kept for the path back - const back = new Uint8Array(sliceCount * beamWidth); - const newDeltas = new Int8Array(groupCount * beamWidth); - - const groupDelta = new Int32Array(groupCount); - const choice = new Int32Array(maxActive); - - for (let t = 0; t < sliceCount; t++) { - const activeStart = activeBase[t]; - const activeEnd = activeBase[t + 1]; - const activeLength = activeEnd - activeStart; - const newStart = newGroupBase[t]; - const newCount = newGroupBase[t + 1] - newStart; - - let candidateCount = 0; - let sequence = 0; - const previousCount = t === 0 ? 1 : stateCount; - const previousActiveStart = t === 0 ? 0 : activeBase[t - 1]; - const previousActiveLength = t === 0 ? 0 : activeStart - previousActiveStart; - scores[TabFingeringRun._scoreGapQuarters] = - t === 0 ? 0 : (this._sliceTick[t] - this._sliceTick[t - 1]) / TabFingeringRun._ticksPerQuarter; - - for (let p = 0; p < previousCount; p++) { - let previousUnplayable = 0; - let previousMoved = 0; - let previousRest = 0; - scores[TabFingeringRun._scorePreviousCenter] = -1; - if (t > 0) { - previousUnplayable = stateUnplayable[p]; - previousMoved = stateMoved[p]; - previousRest = stateRest[p]; - scores[TabFingeringRun._scorePreviousCenter] = stateCenter[p]; - // groups continuing from the previous slice keep their delta - for (let a = 0; a < previousActiveLength; a++) { - groupDelta[activeGroups[previousActiveStart + a]] = stateDeltas[p * previousActiveLength + a]; - } - } - - for (let k = 0; k < newCount; k++) { - choice[k] = 0; - } - - let leaves = 0; - let done = false; - while (!done && leaves < options.maxLeavesPerState) { - for (let k = 0; k < newCount; k++) { - const g = newGroupIds[newStart + k]; - groupDelta[g] = this._groupOptions[this._groupOptionBase[g] + choice[k]]; - } - leaves++; - - this._scoreSlice(t, groupDelta); - candidateUnplayable[scored] = previousUnplayable + this._scoreUnplayable; - candidateMoved[scored] = previousMoved + this._scoreMoved; - candidateRest[scored] = previousRest + scores[TabFingeringRun._scoreRest]; - candidateCenter[scored] = scores[TabFingeringRun._scoreCenter]; - candidateSequence[scored] = sequence; - - // candidates are interchangeable for later slices if all continuing groups agree - let slot = -1; - for (let c = 0; c < candidateCount && slot < 0; c++) { - let same = true; - for (let a = 0; a < activeLength && same; a++) { - const g = activeGroups[activeStart + a]; - if (groupLast[g] > t && candidateDeltas[c * activeLength + a] !== groupDelta[g]) { - same = false; - } - } - if (same) { - slot = c; - } - } - - let write = -1; - if (slot >= 0) { - if ( - TabFingeringRun._isCandidateBefore( - scored, - slot, - candidateUnplayable, - candidateMoved, - candidateRest, - candidateSequence - ) - ) { - write = slot; - } - } else if (candidateCount < beamWidth) { - write = candidateCount; - candidateCount++; - } else { - let worst = 0; - for (let c = 1; c < candidateCount; c++) { - if ( - TabFingeringRun._isCandidateBefore( - worst, - c, - candidateUnplayable, - candidateMoved, - candidateRest, - candidateSequence - ) - ) { - worst = c; - } - } - if ( - TabFingeringRun._isCandidateBefore( - scored, - worst, - candidateUnplayable, - candidateMoved, - candidateRest, - candidateSequence - ) - ) { - write = worst; - } - } - - if (write >= 0) { - candidateUnplayable[write] = candidateUnplayable[scored]; - candidateMoved[write] = candidateMoved[scored]; - candidateRest[write] = candidateRest[scored]; - candidateCenter[write] = candidateCenter[scored]; - candidateBack[write] = p; - candidateSequence[write] = sequence; - for (let a = 0; a < activeLength; a++) { - candidateDeltas[write * activeLength + a] = groupDelta[activeGroups[activeStart + a]]; - } - } - sequence++; - - // next combination of the new groups' options - let n = newCount - 1; - while (n >= 0) { - const g = newGroupIds[newStart + n]; - choice[n]++; - if (choice[n] < this._groupOptionBase[g + 1] - this._groupOptionBase[g]) { - break; - } - choice[n] = 0; - n--; - } - if (n < 0) { - done = true; - } - } - } - - // the candidates become the states of this slice, best first - candidateCommitted.fill(0); - for (let k = 0; k < candidateCount; k++) { - let best = -1; - for (let c = 0; c < candidateCount; c++) { - if ( - candidateCommitted[c] === 0 && - (best < 0 || - TabFingeringRun._isCandidateBefore( - c, - best, - candidateUnplayable, - candidateMoved, - candidateRest, - candidateSequence - )) - ) { - best = c; - } - } - candidateCommitted[best] = 1; - stateUnplayable[k] = candidateUnplayable[best]; - stateMoved[k] = candidateMoved[best]; - stateRest[k] = candidateRest[best]; - stateCenter[k] = candidateCenter[best]; - back[t * beamWidth + k] = candidateBack[best]; - for (let a = 0; a < activeLength; a++) { - stateDeltas[k * activeLength + a] = candidateDeltas[best * activeLength + a]; - } - for (let j = 0; j < newCount; j++) { - newDeltas[newStart * beamWidth + k * newCount + j] = - candidateDeltas[best * activeLength + newGroupPositions[newStart + j]]; - } - } - stateCount = candidateCount; - } - - // follow the best path back, each group takes the delta chosen in its first slice - const result = new Int32Array(groupCount); - let state = 0; - for (let t = sliceCount - 1; t >= 0; t--) { - const newStart = newGroupBase[t]; - const newCount = newGroupBase[t + 1] - newStart; - for (let j = 0; j < newCount; j++) { - result[newGroupIds[newStart + j]] = newDeltas[newStart * beamWidth + state * newCount + j]; - } - state = back[t * beamWidth + state]; - } - return result; - } - - /** - * Whether candidate a ranks before candidate b: better costs, then generated earlier. - */ - private static _isCandidateBefore( - a: number, - b: number, - unplayable: Int32Array, - moved: Int32Array, - rest: number[], - sequence: Int32Array - ): boolean { - if (unplayable[a] !== unplayable[b]) { - return unplayable[a] < unplayable[b]; - } - if (moved[a] !== moved[b]) { - return moved[a] < moved[b]; - } - if (rest[a] !== rest[b]) { - return rest[a] < rest[b]; - } - return sequence[a] < sequence[b]; - } - - // inputs and results of _scoreSlice which are no integers - private static readonly _scorePreviousCenter: number = 0; - private static readonly _scoreGapQuarters: number = 1; - private static readonly _scoreRest: number = 2; - private static readonly _scoreCenter: number = 3; - private readonly _scores: number[] = [0, 0, 0, 0]; - - private _scoreUnplayable: number = 0; - private _scoreMoved: number = 0; - - private _scoreSlice(t: number, groupDelta: Int32Array): void { - const scores = this._scores; - const previousCenter = scores[TabFingeringRun._scorePreviousCenter]; - const options = this._options; - let unplayable = 0; - let moved = 0; - let rest = 0; - let usedStrings = 0; - let frettedCount = 0; - let fretSum = 0; - let minFret = 0; - let maxFret = 0; - - for (let k = this._sliceNoteBase[t]; k < this._sliceNoteBase[t + 1]; k++) { - const i = this._sliceNotes[k]; - const delta = groupDelta[this._group[i]]; - const str = this._originalString[i] + delta; - if (!this._evaluate(i, str)) { - unplayable++; - } - if (delta !== 0) { - moved++; - } - const stringBit = 1 << (str - 1); - if ((usedStrings & stringBit) !== 0) { - unplayable++; - } else { - usedStrings |= stringBit; - } - - const kind = this._kind[i]; - if (kind === TabFingeringRun._kindDead || this._evalNode >= 0) { - continue; - } - if ((this._evalFlags & TabFingeringSegment.flagAsArtificial) !== 0) { - rest += options.asArtificialPenalty; - } - const fret = this._evalFret; - if (fret === 0) { - rest += options.openStringBonus; - } else if (fret > 0) { - if (frettedCount === 0 || fret < minFret) { - minFret = fret; - } - if (frettedCount === 0 || fret > maxFret) { - maxFret = fret; - } - frettedCount++; - fretSum += fret; - } - if (fret > options.highFretThreshold) { - rest += (fret - options.highFretThreshold) * options.highFretPenaltyWeight; - } - } - - for (let k = this._soundBase[t]; k < this._soundBase[t + 1]; k++) { - const i = this._soundNotes[k]; - const str = this._originalString[i] + groupDelta[this._group[i]]; - if ((usedStrings & (1 << (str - 1))) !== 0) { - rest += options.occupancyPenalty; - } - } - - let center = previousCenter; - if (frettedCount > 0) { - const span = maxFret - minFret; - rest += span * options.spanWeight; - if (span > options.maxSpan) { - rest += (span - options.maxSpan) * options.overSpanPenalty; - } - center = fretSum / frettedCount; - if (previousCenter >= 0) { - rest += - (Math.abs(center - previousCenter) * options.handMovementWeight) / - (1 + scores[TabFingeringRun._scoreGapQuarters]); - } - } - - this._scoreUnplayable = unplayable; - this._scoreMoved = moved; - scores[TabFingeringRun._scoreRest] = rest; - scores[TabFingeringRun._scoreCenter] = center; - } -} diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-down.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-down.png index 4060d6e9b9522d987b80175ca35aed33c7b5eccd..c8c4735168773cc52ca601face056c285d08b725 100644 GIT binary patch literal 26522 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

N3BZY31Dt~j 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 z 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 { + /** + * @static + */ + function load(tex: string): Score { + const settings = new Settings(); + return ScoreLoader.loadAlphaTex(tex, settings); + } + + /** + * Renders the tab and describes every note as `fret.string` in alphaTex string numbering, + * plus `*` when it moved to another string and `!` when it is unplayable. + * @static + */ + function display(tex: string): string[][] { + const score = load(tex); + const settings = new Settings(); + settings.core.engine = 'svg'; + settings.display.staveProfile = StaveProfile.Tab; + const renderer = new ScoreRenderer(settings); + renderer.width = 1500; + renderer.renderScore(score, [0]); + + const staff = score.tracks[0].staves[0]; + const stringCount = staff.tuning.length; + const bars: string[][] = []; + for (const bar of staff.bars) { + const tab = renderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar) as TabBarRenderer; + const result: string[] = []; + for (const voice of bar.voices) { + for (const beat of voice.beats) { + for (const note of beat.notes) { + const glyph = tab.getNoteGlyph(note)!; + let s = `${glyph.displayFret}.${stringCount - glyph.displayString + 1}`; + if (glyph.isMoved) { + s += '*'; + } + if (glyph.isUnplayable) { + s += '!'; + } + result.push(s); + } + } + } + bars.push(result); + } + return bars; + } + + it('is inactive without transposition and on percussion', () => { + expect(TabFingering.isActive(load('3.3').tracks[0].staves[0])).toBe(false); + const staff = load('\\transpose -4 3.3').tracks[0].staves[0]; + expect(TabFingering.isActive(staff)).toBe(true); + staff.isPercussion = true; + expect(TabFingering.isActive(staff)).toBe(false); + }); + + it('keeps strings when the shifted frets are playable', () => { + expect(display('\\transpose 2 3.3 5.2 0.1 | 12.6')).toEqual([['5.3', '7.2', '2.1'], ['14.6']]); + }); + + it('moves notes below the open string to lower strings', () => { + expect(display('\\transpose -4 3.5 2.4 5.3 0.6')).toEqual([['4.6*', '3.5*', '1.3', '-4.6!']]); + }); + + it('places chord notes on distinct strings', () => { + expect(display('\\transpose -4 (0.1 0.2)')).toEqual([['1.2*', '0.3*']]); + }); + + it('keeps tied notes on the string of their origin', () => { + expect(display('\\transpose -4 3.5 3.5 | -.5 2.4')).toEqual([ + ['4.6*', '4.6*'], + ['4.6*', '3.5*'] + ]); + }); + + it('moves hammer-ons and slides as a whole', () => { + expect(display('\\transpose -4 2.3{h} 4.3 2.3{ss} 4.3')).toEqual([['3.4*', '5.4*', '3.4*', '5.4*']]); + }); + + it('allows pull-offs to open strings', () => { + expect(display('\\transpose -2 6.3{h} 2.3')).toEqual([['4.3', '0.3']]); + }); + + it('does not bend on open strings', () => { + expect(display('\\transpose -4 4.3{b (0 4)}')).toEqual([['5.4*']]); + }); + + it('moves natural harmonics to the node of the transposed pitch', () => { + expect(display('\\transpose 7 12.6{nh}')).toEqual([['7.6']]); + expect(display('\\transpose -4 12.5{nh}')).toEqual([['8.5!']]); + }); + + it('ignores the fret of dead notes', () => { + expect(display('\\transpose -4 0.6{x}')).toEqual([['-4.6']]); + }); + + it('requires a playable trill fret', () => { + expect(display('\\transpose -5 5.3{tr 7 16}')).toEqual([['0.3']]); + expect(display('\\transpose -6 5.3{tr 7 16}')).toEqual([['4.4*']]); + }); + + it('handles re-entrant tunings', () => { + expect(display('\\tuning A4 E4 C4 G4 \\transpose -6 2.1')).toEqual([['1.2*']]); + }); + + it('handles bass tunings', () => { + expect(display('\\tuning G2 D2 A1 E1 \\transpose -1 0.3 0.4')).toEqual([['4.4*', '-1.4!']]); + }); + + it('counts the fret limit from the capo', () => { + expect(display('\\capo 2 \\transpose 3 20.1')).toEqual([['23.1!']]); + expect(display('\\capo 2 \\transpose 2 20.1')).toEqual([['22.1']]); + }); + + it('keeps grace notes connected to their main note', () => { + expect(display('\\transpose -4 2.3{ss} {gr ob} 4.3')).toEqual([['3.4*', '5.4*']]); + }); + + it('fingers repeated bars identically', () => { + const result = display('\\transpose -4 3.5 2.4 0.3 | 3.5 2.4 0.3'); + expect(result[1]).toEqual(result[0]); + }); +}); diff --git a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts b/packages/alphatab/test/rendering/TabFingeringSolver.test.ts deleted file mode 100644 index 275ae2f4e8..0000000000 --- a/packages/alphatab/test/rendering/TabFingeringSolver.test.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { AlphaTexImporter } from '@coderline/alphatab/importer/AlphaTexImporter'; -import type { Note } from '@coderline/alphatab/model/Note'; -import type { Score } from '@coderline/alphatab/model/Score'; -import type { Staff } from '@coderline/alphatab/model/Staff'; -import { TabFingeringSegment } from '@coderline/alphatab/rendering/utils/TabFingeringSegment'; -import { TabFingeringSolver } from '@coderline/alphatab/rendering/utils/TabFingeringSolver'; -import { Settings } from '@coderline/alphatab/Settings'; -import { describe, expect, it } from 'vitest'; - -describe('TabFingeringSolverTest', () => { - /** - * @static - */ - function parseTex(tex: string): Score { - const importer = new AlphaTexImporter(); - importer.logErrors = true; - importer.initFromString(tex, new Settings()); - return importer.readScore(); - } - - /** - * @static - */ - function solveStaff(staff: Staff): (TabFingeringSegment | null)[] { - const segments: (TabFingeringSegment | null)[] = []; - let start = 0; - while (start < staff.bars.length) { - const end = TabFingeringSolver.segmentEnd(staff, start); - const segment = TabFingeringSolver.solve(staff, start, end); - for (let b = start; b <= end; b++) { - segments.push(segment); - } - start = end + 1; - } - return segments; - } - - /** - * Describes the displayed position of every note as `fret.string` in alphaTex string numbering - * plus `*` for moved, `!` for unplayable and `A` for natural harmonics shown as artificial ones. - * @static - */ - function display(staff: Staff): string[][] { - const segments = solveStaff(staff); - const stringCount = staff.tuning.length; - const bars: string[][] = []; - for (const bar of staff.bars) { - const result: string[] = []; - const segment = segments[bar.index]; - for (const voice of bar.voices) { - for (const beat of voice.beats) { - for (const note of beat.notes) { - result.push(describeNote(note, segment, stringCount)); - } - } - } - bars.push(result); - } - return bars; - } - - /** - * @static - */ - function describeNote(note: Note, segment: TabFingeringSegment | null, stringCount: number): string { - if (segment === null) { - return `${note.fret - note.beat.voice.bar.staff.transpositionPitch}.${stringCount - note.string + 1}`; - } - const flags = segment.getFlags(note); - let s = ''; - const node = segment.getNode(note); - if (node >= 0) { - s += `<${TabFingeringSolver.naturalNodeValues[node]}>`; - } else { - s += `${segment.getFret(note)}`; - } - s += `.${stringCount - segment.getString(note) + 1}`; - if ((flags & TabFingeringSegment.flagMoved) !== 0) { - s += '*'; - } - if ((flags & TabFingeringSegment.flagUnplayable) !== 0) { - s += '!'; - } - if ((flags & TabFingeringSegment.flagAsArtificial) !== 0) { - s += 'A'; - } - return s; - } - - /** - * @static - */ - function staffOf(tex: string): Staff { - return parseTex(tex).tracks[0].staves[0]; - } - - it('is inactive without transposition and on percussion', () => { - expect(TabFingeringSolver.isActive(staffOf('3.3'))).toBe(false); - expect(TabFingeringSolver.isActive(staffOf('\\transpose -4 3.3'))).toBe(true); - const percussion = staffOf('\\transpose -4 3.3'); - percussion.isPercussion = true; - expect(TabFingeringSolver.isActive(percussion)).toBe(false); - }); - - it('keeps strings when the shifted frets are playable', () => { - const staff = staffOf('\\transpose 2 3.3 5.2 0.1 | 12.6'); - expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); - expect(display(staff)).toEqual([['5.3', '7.2', '2.1'], ['14.6']]); - }); - - it('moves notes below the open string to lower strings', () => { - const staff = staffOf('\\transpose -4 3.5 2.4 5.3 0.6'); - expect(display(staff)).toEqual([['4.6*', '3.5*', '1.3', '-4.6!']]); - }); - - it('places chord notes on distinct strings', () => { - const staff = staffOf('\\transpose -4 (0.1 0.2)'); - expect(display(staff)).toEqual([['1.2*', '0.3*']]); - }); - - it('keeps tied notes on the string of their origin', () => { - const staff = staffOf('\\transpose -4 3.5 3.5 | -.5 2.4'); - expect(TabFingeringSolver.segmentEnd(staff, 0)).toBe(1); - expect(TabFingeringSolver.segmentStart(staff, 1)).toBe(0); - expect(TabFingeringSolver.isSegmentStart(staff, 1)).toBe(false); - expect(display(staff)).toEqual([ - ['4.6*', '4.6*'], - ['4.6*', '3.5*'] - ]); - }); - - it('moves hammer-ons and slides as a whole', () => { - expect(display(staffOf('\\transpose -4 2.3{h} 4.3 2.3{ss} 4.3'))).toEqual([['3.4*', '5.4*', '3.4*', '5.4*']]); - }); - - it('allows pull-offs to open strings', () => { - const staff = staffOf('\\transpose 2 6.3{h} 2.3'); - expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); - }); - - it('does not bend on open strings', () => { - expect(display(staffOf('\\transpose -4 4.3{b (0 4)}'))).toEqual([['5.4*']]); - }); - - it('remaps natural harmonics to nodes of the transposed pitch', () => { - const sameString = staffOf('\\transpose 7 12.6{nh}'); - expect(TabFingeringSolver.solve(sameString, 0, 0)).toBe(null); - const note = sameString.bars[0].voices[0].beats[0].notes[0]; - expect(TabFingeringSolver.naturalNodeValues[TabFingeringSolver.findNaturalNodeOnModelString(note)]).toBe(7); - - expect(display(staffOf('\\transpose -4 12.5{nh}'))).toEqual([['1.6*A']]); - }); - - it('shows natural harmonics without node on their string as artificial harmonics', () => { - expect(display(staffOf('\\transpose 1 12.6{nh}'))).toEqual([['1.6A']]); - }); - - it('ignores the fret of dead notes', () => { - const staff = staffOf('\\transpose -4 0.6{x}'); - expect(TabFingeringSolver.solve(staff, 0, 0)).toBe(null); - }); - - it('requires a playable trill fret', () => { - expect(TabFingeringSolver.solve(staffOf('\\transpose -5 5.3{tr 7 16}'), 0, 0)).toBe(null); - expect(display(staffOf('\\transpose -6 5.3{tr 7 16}'))).toEqual([['4.4*']]); - }); - - it('handles re-entrant tunings', () => { - expect(display(staffOf('\\tuning A4 E4 C4 G4 \\transpose -6 2.1'))).toEqual([['1.2*']]); - }); - - it('handles bass tunings', () => { - expect(display(staffOf('\\tuning G2 D2 A1 E1 \\transpose -1 0.3 0.4'))).toEqual([['4.4*', '-1.4!']]); - }); - - it('counts the fret limit from the capo', () => { - expect(display(staffOf('\\capo 2 \\transpose 3 20.1'))).toEqual([['23.1!']]); - expect(display(staffOf('\\capo 2 \\transpose 2 20.1'))).toEqual([['22.1']]); - }); - - it('avoids collisions across voices', () => { - const staff = staffOf('\\transpose -4 \\voice 0.1 \\voice 1.2'); - expect(display(staff)).toEqual([['1.2*', '1.3*']]); - }); - - it('keeps grace notes connected to their main note', () => { - expect(display(staffOf('\\transpose -4 2.3{ss} {gr ob} 4.3'))).toEqual([['3.4*', '5.4*']]); - }); - - it('fingers repeated bars identically', () => { - const result = display(staffOf('\\transpose -4 3.5 2.4 0.3 | 3.5 2.4 0.3')); - expect(result[1]).toEqual(result[0]); - }); - - it('is deterministic', () => { - const tex = '\\transpose -4 (0.1 0.2 0.3) (3.5 2.4) 0.6 | (0.1 1.2) 3.3{h} 5.3'; - expect(display(staffOf(tex))).toEqual(display(staffOf(tex))); - }); -}); diff --git a/website/docs/features/render/guitar-tablature.mdx b/website/docs/features/render/guitar-tablature.mdx index 2abcae2596..2c9b2c391b 100644 --- a/website/docs/features/render/guitar-tablature.mdx +++ b/website/docs/features/render/guitar-tablature.mdx @@ -44,9 +44,9 @@ Because these are settings on the `notation` group, they apply to every staff in ## Transposed tablature {#transposed-tablature} -[`notation.transpositionPitches`](/docs/reference/settings/notation/transpositionpitches) shifts a track by a number of semitones for display and playback. On the tab staff, a note keeps its string and fret position shifted by the transposition while that fret is playable. When the fret would drop below the open string or rise beyond the 24th fret, alphaTab moves the note to another string. It picks the position which keeps the hand closest to the surrounding notes and keeps chord notes on separate strings. +[`notation.transpositionPitches`](/docs/reference/settings/notation/transpositionpitches) shifts a track by a number of semitones for display and playback. On the tab staff, a note keeps its string and fret position shifted by the transposition while that fret is playable. When the fret would drop below the open string or rise beyond the 24th fret, alphaTab moves the note to another string. It picks the string whose fret is closest to the previous notes and keeps chord notes on separate strings. -Notes connected by ties, slides, and hammer-ons or pull-offs move together, so they stay on one string. Bends, slides, and vibrato never land on an open string. Natural harmonics move to the node that sounds the transposed pitch. When no string has such a node, the tab shows an artificial harmonic an octave above the fretted note. +Notes connected by ties, slides, and hammer-ons or pull-offs move together, so they stay on one string. Bends, slides, and vibrato never land on an open string. Natural harmonics move to the node that sounds the transposed pitch. When no string has such a node, the harmonic counts as unplayable. The example below is transposed down four semitones. The open strings and the low notes no longer fit on their strings: From 2063d768e92024cb49f1a9375dfffcf1395434d9 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 16:49:31 +0100 Subject: [PATCH 11/12] fix(rendering): keep unplayable transposed tab notes off strings taken by other notes A note which no string can play keeps its own string only if no other note of the beat took it; otherwise it moves to the free string where its fret is closest to the neck instead of overlapping the other note. --- .../src/rendering/utils/TabFingering.ts | 42 +++++- .../test/rendering/TabFingering.test.ts | 133 ------------------ 2 files changed, 41 insertions(+), 134 deletions(-) delete mode 100644 packages/alphatab/test/rendering/TabFingering.test.ts diff --git a/packages/alphatab/src/rendering/utils/TabFingering.ts b/packages/alphatab/src/rendering/utils/TabFingering.ts index 2d7d721570..74cafd0f45 100644 --- a/packages/alphatab/src/rendering/utils/TabFingering.ts +++ b/packages/alphatab/src/rendering/utils/TabFingering.ts @@ -109,20 +109,60 @@ export class TabFingering { bestString = str; } } + if (bestCost === Number.POSITIVE_INFINITY) { + bestString = TabFingering._unplayableString(n, usedStrings); + } TabFingering._place(next, bestString, n.string); usedStrings |= 1 << (bestString - 1); } } + /** + * The string for a note no string can play: its own string if free, otherwise the free string + * where its fret is closest to the frets of the neck. + */ + private static _unplayableString(n: Note, usedStrings: number): number { + if ((usedStrings & (1 << (n.string - 1))) === 0) { + return n.string; + } + const staff = n.beat.voice.bar.staff; + const maxFret = Math.max(TabFingering._maxFret - staff.capo, n.fret); + let bestString = n.string; + let bestDistance = Number.POSITIVE_INFINITY; + for (let str = 1; str <= staff.tuning.length; str++) { + if ((usedStrings & (1 << (str - 1))) !== 0) { + continue; + } + const fret = TabFingering._unplayableFret(n, str); + const distance = fret < 0 ? -fret : Math.max(0, fret - maxFret); + if (distance < bestDistance) { + bestDistance = distance; + bestString = str; + } + } + return bestString; + } + private static _place(g: NoteNumberGlyph, str: number, modelString: number): void { const fret = TabFingering._fretOn(g.note, str); if (Number.isNaN(fret)) { - g.setDisplay(str, TabFingering._modelFret(g.note), str !== modelString, true); + g.setDisplay(str, TabFingering._unplayableFret(g.note, str), str !== modelString, true); } else { g.setDisplay(str, fret, str !== modelString, false); } } + /** + * The out-of-range fret shown for a note which cannot be played on the given string. + */ + private static _unplayableFret(n: Note, str: number): number { + if (str === n.string || TabFingering._isNaturalHarmonic(n)) { + return TabFingering._modelFret(n); + } + const staff = n.beat.voice.bar.staff; + return n.realValueWithoutHarmonic - staff.capo - Note.getStringTuning(staff, str); + } + /** * The model fret shifted by the transposition, shown for untransposed staves and unplayable notes. */ diff --git a/packages/alphatab/test/rendering/TabFingering.test.ts b/packages/alphatab/test/rendering/TabFingering.test.ts deleted file mode 100644 index 86e64a2f4f..0000000000 --- a/packages/alphatab/test/rendering/TabFingering.test.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { ScoreLoader } from '@coderline/alphatab/importer/ScoreLoader'; -import type { Score } from '@coderline/alphatab/model/Score'; -import { ScoreRenderer } from '@coderline/alphatab/rendering/ScoreRenderer'; -import { TabBarRenderer } from '@coderline/alphatab/rendering/TabBarRenderer'; -import { TabFingering } from '@coderline/alphatab/rendering/utils/TabFingering'; -import { Settings } from '@coderline/alphatab/Settings'; -import { StaveProfile } from '@coderline/alphatab/StaveProfile'; -import { describe, expect, it } from 'vitest'; - -describe('TabFingeringTest', () => { - /** - * @static - */ - function load(tex: string): Score { - const settings = new Settings(); - return ScoreLoader.loadAlphaTex(tex, settings); - } - - /** - * Renders the tab and describes every note as `fret.string` in alphaTex string numbering, - * plus `*` when it moved to another string and `!` when it is unplayable. - * @static - */ - function display(tex: string): string[][] { - const score = load(tex); - const settings = new Settings(); - settings.core.engine = 'svg'; - settings.display.staveProfile = StaveProfile.Tab; - const renderer = new ScoreRenderer(settings); - renderer.width = 1500; - renderer.renderScore(score, [0]); - - const staff = score.tracks[0].staves[0]; - const stringCount = staff.tuning.length; - const bars: string[][] = []; - for (const bar of staff.bars) { - const tab = renderer.layout!.getRendererForBar(TabBarRenderer.StaffId, bar) as TabBarRenderer; - const result: string[] = []; - for (const voice of bar.voices) { - for (const beat of voice.beats) { - for (const note of beat.notes) { - const glyph = tab.getNoteGlyph(note)!; - let s = `${glyph.displayFret}.${stringCount - glyph.displayString + 1}`; - if (glyph.isMoved) { - s += '*'; - } - if (glyph.isUnplayable) { - s += '!'; - } - result.push(s); - } - } - } - bars.push(result); - } - return bars; - } - - it('is inactive without transposition and on percussion', () => { - expect(TabFingering.isActive(load('3.3').tracks[0].staves[0])).toBe(false); - const staff = load('\\transpose -4 3.3').tracks[0].staves[0]; - expect(TabFingering.isActive(staff)).toBe(true); - staff.isPercussion = true; - expect(TabFingering.isActive(staff)).toBe(false); - }); - - it('keeps strings when the shifted frets are playable', () => { - expect(display('\\transpose 2 3.3 5.2 0.1 | 12.6')).toEqual([['5.3', '7.2', '2.1'], ['14.6']]); - }); - - it('moves notes below the open string to lower strings', () => { - expect(display('\\transpose -4 3.5 2.4 5.3 0.6')).toEqual([['4.6*', '3.5*', '1.3', '-4.6!']]); - }); - - it('places chord notes on distinct strings', () => { - expect(display('\\transpose -4 (0.1 0.2)')).toEqual([['1.2*', '0.3*']]); - }); - - it('keeps tied notes on the string of their origin', () => { - expect(display('\\transpose -4 3.5 3.5 | -.5 2.4')).toEqual([ - ['4.6*', '4.6*'], - ['4.6*', '3.5*'] - ]); - }); - - it('moves hammer-ons and slides as a whole', () => { - expect(display('\\transpose -4 2.3{h} 4.3 2.3{ss} 4.3')).toEqual([['3.4*', '5.4*', '3.4*', '5.4*']]); - }); - - it('allows pull-offs to open strings', () => { - expect(display('\\transpose -2 6.3{h} 2.3')).toEqual([['4.3', '0.3']]); - }); - - it('does not bend on open strings', () => { - expect(display('\\transpose -4 4.3{b (0 4)}')).toEqual([['5.4*']]); - }); - - it('moves natural harmonics to the node of the transposed pitch', () => { - expect(display('\\transpose 7 12.6{nh}')).toEqual([['7.6']]); - expect(display('\\transpose -4 12.5{nh}')).toEqual([['8.5!']]); - }); - - it('ignores the fret of dead notes', () => { - expect(display('\\transpose -4 0.6{x}')).toEqual([['-4.6']]); - }); - - it('requires a playable trill fret', () => { - expect(display('\\transpose -5 5.3{tr 7 16}')).toEqual([['0.3']]); - expect(display('\\transpose -6 5.3{tr 7 16}')).toEqual([['4.4*']]); - }); - - it('handles re-entrant tunings', () => { - expect(display('\\tuning A4 E4 C4 G4 \\transpose -6 2.1')).toEqual([['1.2*']]); - }); - - it('handles bass tunings', () => { - expect(display('\\tuning G2 D2 A1 E1 \\transpose -1 0.3 0.4')).toEqual([['4.4*', '-1.4!']]); - }); - - it('counts the fret limit from the capo', () => { - expect(display('\\capo 2 \\transpose 3 20.1')).toEqual([['23.1!']]); - expect(display('\\capo 2 \\transpose 2 20.1')).toEqual([['22.1']]); - }); - - it('keeps grace notes connected to their main note', () => { - expect(display('\\transpose -4 2.3{ss} {gr ob} 4.3')).toEqual([['3.4*', '5.4*']]); - }); - - it('fingers repeated bars identically', () => { - const result = display('\\transpose -4 3.5 2.4 0.3 | 3.5 2.4 0.3'); - expect(result[1]).toEqual(result[0]); - }); -}); From 824b977b5f6be3da2b73a6f496a38bcbbe79b8a2 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 1 Nov 2026 16:49:31 +0100 Subject: [PATCH 12/12] test(rendering): cover transposed tabs with visual tests of original and transposed track Each case renders the original track and the track transposed through notation.transpositionPitches one above the other. Replaces the render-based unit test harness, which the visual cases now cover. --- .../guitar-tabs/transpose-bass.png | Bin 0 -> 31554 bytes .../guitar-tabs/transpose-bends.png | Bin 0 -> 35023 bytes .../guitar-tabs/transpose-capo.png | Bin 0 -> 33692 bytes .../guitar-tabs/transpose-chords.png | Bin 0 -> 32836 bytes .../guitar-tabs/transpose-dead-notes.png | Bin 0 -> 31674 bytes .../guitar-tabs/transpose-down.png | Bin 26522 -> 54475 bytes .../guitar-tabs/transpose-grace-notes.png | Bin 0 -> 28052 bytes .../guitar-tabs/transpose-keep-strings.png | Bin 0 -> 28670 bytes .../guitar-tabs/transpose-legato.png | Bin 0 -> 30000 bytes .../guitar-tabs/transpose-multi-voice.png | Bin 0 -> 30091 bytes .../transpose-natural-harmonics-down.png | Bin 0 -> 32054 bytes .../transpose-natural-harmonics-up.png | Bin 0 -> 32302 bytes .../guitar-tabs/transpose-open-strings.png | Bin 0 -> 29355 bytes .../transpose-pull-off-to-open.png | Bin 0 -> 31454 bytes .../guitar-tabs/transpose-repeated-bars.png | Bin 0 -> 31594 bytes .../guitar-tabs/transpose-ties.png | Bin 0 -> 33225 bytes .../guitar-tabs/transpose-trills.png | Bin 0 -> 30603 bytes .../guitar-tabs/transpose-ukulele.png | Bin 0 -> 27738 bytes .../visual-tests/guitar-tabs/transpose-up.png | Bin 8174 -> 38563 bytes .../TabFingeringPartialUpdate.test.ts | 4 +- .../visualTests/features/GuitarTabs.test.ts | 74 +++++++++++------- 21 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-bass.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-bends.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-capo.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-chords.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-dead-notes.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-grace-notes.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-keep-strings.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-legato.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-multi-voice.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-natural-harmonics-down.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-natural-harmonics-up.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-open-strings.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-pull-off-to-open.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-repeated-bars.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-ties.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-trills.png create mode 100644 packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-ukulele.png diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-bass.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-bass.png new file mode 100644 index 0000000000000000000000000000000000000000..586b07cb68163ebccd242b2233006503e68c3bbd GIT binary patch literal 31554 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%0AbIN?egdFf9w>i@SXDQyg55gUT9Zwq%9#{fr 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⋘32-$?SBeo5)CI<8)0O?O2w`PIjWIB1G`o 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 RC#d_85R(?of2H&Be*sw>$E5%O literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-capo.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-capo.png new file mode 100644 index 0000000000000000000000000000000000000000..939def5dd6c938710d8cbef51ced2d7a9b0d236e GIT binary patch literal 33692 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�c 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

-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%0A2k8UhA%IkxAp{WS4QvZ9fRCVXHzddOL?>#ZEz0 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

N3BZY31Dt~j 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 z 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

UwkZFS$L5yY33R!wh3MeANHa`a{%RkA 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 Dx(AuY literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-keep-strings.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-keep-strings.png new file mode 100644 index 0000000000000000000000000000000000000000..ca52646bc201af035fdeef3e3cc6203495b1d204 GIT binary patch literal 28670 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 J{A>3D{}=n;{d@ob literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-legato.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-legato.png new file mode 100644 index 0000000000000000000000000000000000000000..dbda3fe954721bc0ce9a70695c1b35b181405494 GIT binary patch literal 30000 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 literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-multi-voice.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-multi-voice.png new file mode 100644 index 0000000000000000000000000000000000000000..aecc1f6916731d088957f97eb15629192aa2a029 GIT binary patch literal 30091 zcmeFZg;!K<_dh%|N{JvH3JB65N{32`fFMXo3Ifs~HN;RVNGm9v(%oI7lt>IcG($)a zL)Q?$Bg6eX-+uprcNS{_=jwg!{n>dYSpB&o$#uHxAP|T|>8YFs2!uxo0%6S);sa0O zO&?tVzi^$OD7_>EKHh|HK7l~DK}vFuUxJf1raj^e%#$z9++D@5C2#Uf-{H}_-Sp

M9+pXMrvA*P6!riA02J_?PUEYl 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 T4K^@z?|JBk_Vps=dyoGM^kGo_ literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-natural-harmonics-down.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-natural-harmonics-down.png new file mode 100644 index 0000000000000000000000000000000000000000..8e9804bd023e0d58f103b9ce834bbdbee467313b GIT binary patch literal 32054 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 Uv0ZCw@1S=vYm>@U;<`&Ey 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≈fHS@->ZmB=K#O^Ab#P|gkTu~03BGCe!u`BP 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 literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-pull-off-to-open.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-pull-off-to-open.png new file mode 100644 index 0000000000000000000000000000000000000000..be669748235fa2f4e6367352f9d827f67ccbb3cc GIT binary patch literal 31454 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 literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-trills.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-trills.png new file mode 100644 index 0000000000000000000000000000000000000000..f3834051cb1bad25e8352507b2ca73885e924a9b GIT binary patch literal 30603 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 literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-ukulele.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-ukulele.png new file mode 100644 index 0000000000000000000000000000000000000000..dc0098e358533bdc5c7f4b9408000d80da5e2358 GIT binary patch literal 27738 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 L{gtPF`|1A!REYz3 literal 0 HcmV?d00001 diff --git a/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-up.png b/packages/alphatab/test-data/visual-tests/guitar-tabs/transpose-up.png index 6b7651ebbf7f37fc3f61f6daf6689292a0a16ffa..ac4e113d14ade5d23d9a62d891cc91c26e2b4d1e 100644 GIT binary patch literal 38563 zcmeFZcT`hv(>4kTMWiWRs?w!O@1P=05Co|ry(%4~x5NU{1*A6-5Rnp^^gxs*H6p!* z2-15mf#hu9_k7R$yyrdZoORas=jUPx3$yQi@408Lx#pVLMm*M5BfrXc6%P-OTtoeV z9v&Vc4IUoo))gY)H%bSRe!w>ZulpMMSAai3S8U(m;oZd3cyLeOFLP}=Fw?*eezc9u zW+DSilUb9b-w~Vo&XoG42%;t^I1np^_R~;EPM_973X6SzVw^RUXPifl^INuq!fNBe)4-tP`FaSa zM#BI30xU4Jz?W_eGbKenxjNLwKm4O6KTDSmX^~@1%zj~^hS*AL;$QCqEZHBEpVHRR zk5#|6i6zn|?w`H~SAZ&kz|a`E8y0S8Dl{08n&qrq>cHS`3$~*KYfj2!AN(S&1Nlk0 zKNX7&R4Ug&HLD;tpUNm+EIdS#L?Z_wVy5qE2!uL8#qWp(5K1oGMz3&Jw@^vf5OzI) z497!`$=|!&lY7C^i6@LV1Ev6*6S@)~xc=~}Dt<~Lk1s#nJEw@(1ZpA>01M$6R_jJz z9BNVG^1Fy+4}>`SR6W%ex(L<5C(Y~sBQoSgy>$znwKO2jPQ~G-26sjHS>l$K{hn}M zcY=~5RuQ>~W`v<-?b3XWsPOohQh??LEBuF{TEZ>?+6_^qa+F;ST;pbQbUX?b?hJm$ zcId{tWw^&ZO?jlrJj&!}vF9!jVcrVQHc1A}OOksg75iDhS*&ZPz5`w3CG!tfG5VZ*IwYN-~}iS$7@dId+PS(%fW zrL$4t>=@*Ov)|H-W9l1OM48NX-iS~&(P|6%ya#$a{D>SV2jq!$sOW-HXVuAljv39C zrgie|;A^A%MNLkL7jZaI(8QAven$F1@Es})ZxPQIJk3$@gi2uu75V1+0QFi%gbzJ8 zozAi0o)AZ@DHEI=9}BJ%P~4Qj|=S|CxRK}Kvbi)NRO)+PItvK`aNwDMAuEErp>PGE1NzA6$?v+~JdBDg|&rqXpU zE)*Sx7*AMj^FF)At|j|zFLmoH%fH&*FHA#lS|7-}GcvSUTIO=5C$6^dZr6RRg zm}6WT@5ta;XNvVwh&{0gPXR|ov(SRgGx}CUq9Wll>MpGd+{ouX-*n4^9XCJgneXvU zUF0`du5~4ys_-6kYfc1RJ@Vm9U{x<^YjP0SNf6@`DSTEdZB!Qiw?TdD@2oMYfKFQl znKx%J`|+tY3acCcPBVZ1Cij4+(yQA(b zx3mSlZSxASB@0K9*U4uu=CoViZd4O)zrG#h5}Dg47g_(_8JZpOK)7>7J^JB=eI+#2 zOy~Wb_D(R)oaV6+e{xc|!&um8B3g)dW7pZ>?Rpi)?IDP_@#Qi%13cj@yF%tP5kCkk z+&i)cLb$19IILY8<|`~!xwec;uE~qXyJu1@VyO9QUeC(hVCrfijK~hcCDnDxI9dPP zF^{j)Y~QVsNq8Maedui|P*W+Jol6SwRY^ED9T-_;ht@i97QmwaVA?+2&55vyjU{|) z9(9s9YoZ_?W`N`FMzQdV$3@&43!S*vd#o{(Y2ZIOUvc%o0FhA|M0uGgBVW|2V@(^yYNTY^lFj>TjCD-tb{f&aGCMXLc4XAK=y10JFmPJnSJKIT zt^wkY4bu*L=k;md70HNbUfAbbLnZgn?PQ5ZUlQHC$O2j7Q&;b>Xr!q4?=vR!oBp+a zGP^s{)X=X~>ol2MJ3V%$rAR#9HmlTjZBgctUzw!%{Z9}=4`PZWlJ3xYN9gqDllm5E3?BJbW=6CzF$#6pXq7y5_ZyHLU z8`ZPXwo`nh{k8xXimExOzHi!BQ7kWYv9kAV7XP1KEp6<)MaCub5!}qRJX@W{>Up`j z`GUF>%!FhSR^vMJOIj~Qx1BbsTERjC(-NrM@w49F9vK;fyOt>;Xe%D~KKHlFny-() zID^KzJjfOYv=ySRPW60re#=B_8OG7CjY;Zmi%6>7-ty!$ zHf`OHC+PMieazIA*BAe@2!A8;%|?HB3!BSx_mTy95vr&>>my7)H>(n#hp;K8{`i`^ zsQ|jtl(W-orspoY&QRV+Tlp}+K`VB6bk{pRh zlY4P|h7QLc`73Q1p%oCf2KZO@)i=(R&}IY5F3&UbLOGxM#69@AqRt%?(`MJgYeD3! z(PjwhjWu_6YjdL5V%)lic0&A+4t3Q{`-6CMR5rsxQl`vtqh2CGQw_ww8(=*jTO6Ze z->mylV0=MWce8Y9yq;|{ChAXB;*-rg-rHU(P^t z)c0>>T2pbf@#0KWIpJ#2u)l(@yso+X?GeD4$4FCW-YnYJF2x*LAlPO@TCT&VLUQ~h zzs`l=Ghg>e2I1(6`EUjCi=U;onwQRusWf1U*WDiV&Kv_=0u*)Cj0V|#dPI>En_X%H z74Bdc&VbGf2Dvgej`js_c#X>O_3vYj1SRL|{W)e`muh9DLwewIfpUDhZkDLcy4#~> z^oQlXobQ#co_-=h#$259i_Zzx#P4|sgYb_6I6FLRR6TDpMVUWi(zwnZ@BW-K#PETh zRSU1Cns8?)$FT}0k0M*^Qzyu#DkhW=tB{~&1GV8OO8gKZtsQOqP?AcyApT2$&}hwj&s3u})~yfmYW8 zitMyZuerbgZZ{lkuBkqM6I#(C9`HT6^F?M7RyUaeeYN#0HZ1 z356kTJ9M6cp(54=x8cl`@^l(?9UI%R*%=)h-d;JFzx!C3{$0@I;bYe;hoJr z&hidby}upmvB@e_SJCTB(CVN+U_J2FA)pc|ms%ETOtE@iTtT|oHs(S5@If$_} z(v}Q(eVfbN(>d${m9=mueCC>hlUv+opgnXKCmtY#N=*5JqQWew z2*_ckXaZ`yfJn{8+#kj0am=`3y;>cJuvf78ttgy zXNoYmgyFktn!L?C2_SwdOn)Tjui8(eLumD|zXABH*EA^Ek3F^6N%Wb#hT$xeovI1E zDb8a`n_~b7QAhkWX>K3LTkTU1nO~Ti6b_SH%w*Nbf61v$L7W{|*`Q7}O+TqjB|&@yE$(@JsQGxpAp5C~&vz}1bFwo|sy$&XP`48$Z)|nnfGekkc0fDUXN7~rTFOB~)M6k`Msk$;?m6qY)*^qON#<>B+xoqL9(2~ZKPI*!;Zs&MLRVN?6d#gwDL8KHPhBR@@K zPqH4}5$hc7FV)F&kfb6il#)Lo7q2fTpYXoE-6TL&xZ~N>F|tq2qa|V$$sNmb%|&7; z!?X5CJCN&Om@^g@vnlD|kn<0sbO7!U2Ea>5vGVQ$QK?Q4G@#npQ^*|(aAkgFSr_QO4B|?K6%KVzv+hO-aoc(CG zW^}Q}oFw6@p6sK_>pJ9ZHKKHH7}ypS#S$2H**8wqNAy*Hmw@VSQfVBjJhStNjq9A{ z1qzO37=Z3rqNZ+GJe{V$GA|*9TcW z;IG+lHB}+|c2qa^HT!}#M#Vkh$M9=Rfv$|0Qr0wI6x2h>P))9D#={0_ydfpR74XfT zaoJAb!h>Y%yVbwuU;W^%xh5R*Mzd0&CCip+nmVV)m%V60utLvGkB^G?cu_mM_Sd&- zA|Ir->ps_{l_XY)jhcSRa_y^2KE>QKH{nb0E##h%mtVL(b;BFf(;5#Hd$id?3L5f}{==t$p#$7-Bt$Y5O&~tyLCv z>pN2Q{-dTW5~Dq~iHY zf`JAc5sgz$`f?rmw7^kBE!ur-VzIe=s04z{-*0TKCBs;2Q(%&}vinq)ByL|W?)`io zF~!ZfNv8_?esHHQf}}rV@;2)~H@32*PV`Nj5cy1RIIh5*6h zJ0&8L^l+abRUzR#s*%?~X<&g&eiAVb4&3oA73+ z{qIB`oo1NCY&{N(351zc*$25|Dtm-5#wI4?$-jU9cHuWH8I#J=PB~nkJbe47H5{2G z>%Gzx85#K!{75iE-hW4|^!la3pr@v9xQ3_y(g2|W=svcbX*j$fQsW^*o<94kTKlT; z0Elj$sz@j{NC>|7dzZ=pMczbt05G?$^Jn_gXYJFgM38bn)bz?k|WN z>*`jNy%mvA8Q93UJd}pA&n4FK-?FUJ@Z?837Qf(yEv{pzf5D(9QedMR4=uSoj%lfj zLmDCklr}utc6UpA>XoEgWr1}&VYE{_#izFov%#0PVTmSbFI#rDjN=~4n4zfnvfSi$ zd3sA)ygrZAq;mVoEbqy+={egq{(ANab-AwoOKzIR&x&%qIV3?9S=P6cu?S1F93s=2 zc<{l0d}NwwtmSGQ!;yG-eU{A&r`sQe%T4$88gJ3PkfHl>+sFOUP%ZQ<>$v%1xA_$I zMmJW9=<4QT<-!W|if+}fi}g!$$h{c);?{C7;lwdoW@c(+V6guXhds-YTS&EGWs>t* zV?yY@o#?W!($P*6wNv457yl1us~asbsnT||7hCR1oL25}qxYYgIuR85g z%p}Xdetl8XS`pr( zP1SjPNO7zEvO@_G%kXC*w5u8ys~lgOuV3%(e)w5CD_{eH5B6+Ke>tO9G(>`c|0@6z zNZN%ymXxfeYjKP5*TSt@!|J^jdS%v2s`{V)&h+{E^{csCY3jp=54k_<6Y%Ft?;thOXgTAX{b%;>Mwot+&gv9w;7`t|+QQ6&k7 z{>R80?hBm(Z~k3(6S!VyN}Uh^V6&iLw9dsU&r_`K>zZ}dG_9|wGinPyuGOKQFugkU z>tV$u_^nfE@qXpkpx9;uF%wLY2bJBO-lLd!N}P$`^s8IsQUmgKs?7F|V@klg&-*%jeO_4zi$Li6ImMQxIMq z#vPv>&ddb%rAy3t$q6;CRVws!cQ2$QCo6ulZjTHeTz=_4(;RHUpcr&CRrI8=zxd0S zF{ZJ`yQV$dI@zaMVz9iApu^JHOt1blX{#S^zV|&Zl-T?SeE_)l)2qe38)pTdZuBi| zZpJdDX?-?{v8@`X#BXtqfdCF!I__ML*AM~mA_M=WEUKwmN!B@9tu;>BFs z>KQIJ+N3<4J5>&+C}?O%Pt=yZZQ^^=UEnUq%=Ec)dytcN+gCXNi}rX;CM6{ejgHO? zO<|HB7HH#bxWuGhA|U`#_;z-7qd-`h)UT5>N%m%mIrKkw$nqXZSg3viKt+I4yS|>D zC;$ltc=7=J&Ls<5gxEcQzU~-7mfYc2 zz)Pic6p#PHq^DLdcoD#N6$eI;zD0hmB%+bLor| z&pxP_eRo6;A~Npoc932QWY6WYBy*+d!xZq9(q`N##l2Zfp)Tzd_b;(oZ0Um+uOdmO z>+3;icA9oT%%$t=iM;G)jlAKPOCLmIY`SJVlxqfRGF!WOX)GVEEYV!QE2l1;&bNJ- zS02~kG3_3l@r5a0-mxfxnPQ4?%A=E|6#$R-QwKL3GIc{X>KC<{l|oM6cf?JZOJ)Rn zc7M3d|Md3fh$8*3JczaNDmA6ktyZ{wU%K~wu?!8JZ29A6?vY@^qqwlEn=Lpj%4wwJ zM$TmOT4fKBp@G4=q{~G0LPxdp&fhMi_-^W}t5da+Ui~r-vu{YKiKGg%M*c}Z8bE>x z69YhE(Ua-lZnjG&-)~>V1_~Kx#0Rj?v})X00r5pQFI6d2F->bB+g`GYGAbEECQ2L2Uzr;nh;wC;yLmeZg*o zQTJc&RI}Kh6=>k^f1JUS6SOm$F{rJg(%xVgy*vSghN)}d*~z|6Uz(Uh_qan2yiR7l zdf}hkyfTyxVMD%Eh+I@27$zs0Qi!j=Fv*M^B*?VBWV}0>G%LMKO4o3)d&Vs|Kdn`2){Z$ zBc2x_21z7cQ@YAPdHR*M)#Z_cy=WS8Ub4Y=Q#&~LOiDCOtBMgI8vk$p7vpCLGdCms zH@X2?w;=7&8J={Ng!TUiRBL!}-{WL&nX7gtWblt$3w)0c{c{Sd&$nOS9yRlHvdz8$ zpI%B2`#m=Ou>e1RBX?p~Z?}uvSh>|kri_=i+-gZxvUp(@kkm&_`9CKlB%H@82n{7> zWvC50-r?8O)QoeoXX@)Ik@(cq6lBGnScG&z{wLxUW}PEmDZ}75AgpSp4o>!0bJ785 z{ZNHe4D|4tc;1J(ECYs$hDS%&3`{2-9-5i;*?jvJT-jv={IqtRLsefquYUWkq`4FH z_FcD+O75m)zOG3q&vmq*rE$e;^;A50qqW^4*^z(E0^Ho0B70`Cc5|nMAdFt_$|ZyS zw!Wi4v$~4W1`IciYfgG(SG5P#SFr807aiv~!u%RIZNFhH0d^EF(qB0&qUp@?U*JJLZFuSJ zl^C%J>S$YZqvu8T&DWZewqDYV1lek#_m8y{k{%`n`E9}v6+F8VhAFjj6oVb;b{H5o zl?bqgADh_9iGNkS{eHQ!D6pR$=6|vo2sI{}B)oI@P5!nI~Fxhd`WL#(2 zY;pN``q6J@C?Qe(GLTu!c(iyu`x3a^9uXfcsVRxhmbXe~yZ4Il2)SsyHnIrb-y$TX zyJO#*x&zc)FZC;(*C)Q&CB&`Hs1@ocUm;78Rww{z+!6aha?cnsjS1LjknZ zWxBz;=Wk7MadB;OQj&!1ZCkHLS+d{u+NgDygSu}QzI=xXZ6%i?OP6vpuiXsAVdVCw zzr7_DZYuu_FypkeElm<8Wy(=IoNx`CSe`HfY zK=q>OKXl#u-5WhqljhTTx2B`nPuprN`?+-AyxOj-m0NxXaX(7mi+L#vHyh8vojRcW z7g_MM<<_g2c6%~b`sFtNHe)uxA1f;pVwj{r?p<6d?m(o}@M41i(hC6Ds2C}kQ+M&4&i!(JY z{Ba5gPA3QJogeSvdT%KnjKOM)r2_V#aoltZ7w5gc^1=yYTN^s8g>x|J+XL9sf)GOQ zXGF!zy^l?2n?M_6-1IJtE^}_ck>@yo;mZrFwYN=#WKOSrd`AdAwsKOp_92qmDcF$@ zE&VE9kHrHENOaBQP7Dtq<_NLLwoonvs-5BvQU?-8yZYCrV{cQ}bdtx^Xms)PFSY~Q zcrhKaLKRh69ZBxL`Cw;@&hn*mD7A5I;<_(*r}366z9MPKOqV2=w;&H5C4RW%V{=mG zf&NR4L-rPRloX-f&A5h1JOb`R5fbuJDj1P_Jc{D&v9 zZD%ci!kCEqGNfRWhb_1>3NfR!`ZkEB#Jlbh_V8#`*TL5thsVqhA?+xl0Sp=?si)NHqsS<8E z-600{aHk2tfzb8ALgW)_9_^qlFxwHr3GuNe*2W?8KO)}WFj+XXV5fu0;f^KZBUa3Q zYA23CsO9w4`pW*AiNXHiRLQw3MD%ArW)^q+IYw{sY)C9iTWNI4W)x)T7yv}^nYDwBn+venzez^sRt_6aOl5$w0Z@IofzRo$8G8ooEq$-^nA=$9JuJON zOFPY=5U@rFEc=REfAd4E{Em8d@WHr`|L1VB8z2M@6N=kR*XK)`oMw|IJ9?=WVjf1$ z)B#Y|Sna|=3*L_7;$jR4fabdA%P#|-D(@4KGm83re`U9RBmMk&iv)*94!T@%U(>M2 z%JgM`$U6Ca8pk4Di+rg6RV)#}5`1go9ITd>C$FxuvaSypXO2MCdI@Y0cRlsxDwIh0YCa3k- z$J44r757iL|5c#z)sxr~M2``5x6l>K*0%jYgo1k@a!@dpT^{KWPzT@0N$K!N7|I6p z(oom_v1#jj3>P6qZ*$)xFbT1b*e2}Gj(BTg{`@<;fJ}Hh2K8vI{iRA1o)D4ii$BL) zMfDr+P;GA)p%?ts`vw=#k_X==Y`&6d@Nta?;SqnzG;wwDbz`*@P$>1pH>!@oPoZb)Yw&O(3V=P~&?ak~A3*M<4^eiXtE%8X_ zfhL0CqYhKYP8kT}e3Ir z*$RRB%HGWf-(V~vZm6b1p2Pjk864pB$2~18Bc+o+|6+~I{R<`?lrSb?lx$cmAVn3J zij5SPHLM(|M9~EoKxh8|s^KVW@ZJDZzanN$MNnaMsOX8Nj{J7p_rgrihv9WNsVVo? zkN&$0-Wcp*%M3dBg&V!OpVgzojcKt_Ghegti03OqMFol6j~IhiiVA&}ZhiirL;K9A z#CRZZp*PJ1%OZcaH#j_M9w-R#QOuXh%F1LR27_NZp(lgE8x5;ve-NZ^yOFZ1B`1_Y zXmFqT_VMX1a&sDH(E>zqFK>5MWzaEyk`zk%H9nYVKSyLPIke6Fc%I(b2nHC3&)6XP z+W8?CDX&~3DX0;3{Pn&2W?Dhm0nyO3r?T%yQ&i5F5K>HB`Ec4A0`JX;9<*CKNZvuGm>&=Sb!O1FYcj$?Z$n)R%2hwJV%>IAl zpNNici}wrxMwQQ6bdNYNAtp=Cgsjs=*FmOdI95+?A-GZ zOPJ7eamiUbfTb_v1d7wljf|>3$G55hlUh@&{+2M%zBVYkyEp^)^xD49NFL!t5I_p< zW#}~myzU$jYF_8f9*)LmvK9ZR4R78)WFJ;tpLu`i`&?rU!{I(l5xY*5N!m1mnCUZu z#MSCf$%)%*;aJb9zPER9zs`o+S_}XAE;twAvb=7X-$!gy`J^@*KTaEtRn_3gjW*nv zFPNftvX*P&=?p?7VF)D@9s2H=)1A1yCcfb|+7msA$R;1UfwwlGT5-XHC)AB}c$=lR zk3G=en|3I{GmiEd7GQ1H1(8;Wxj#k-lua1>&fp7I5d$j-D@gaIfn|&tdh4QxsVBFxLelX(D?aQ=;uEsC$Jc+caOYnQ3nEmXq_vvR^KD! zdaGz@1I!v>upz~DAT>hW$b1Cju7>kcC0_u6+4+Vj9tDNS!kj^OxGT;wmOR9G!#F|- z{V3fT?#OM9!81g1tnGShlcVQ$95Ip~Kc$UwYPfLKM;cIChFXd~&N6bli<&`(1@%8? zIk(mG(ZM1kf7e$o+s#*v(~Tshw~r;!Vs~AkDa0HVb*x7UccjABgC#tAiLE!vS<+1-Q?wS91k`P%+px#MCu7=myiIqjKKY;gSTyip4Va|~nWfG#-tS;? z`vrtW<)mw)OQURxdBF1*q(1Db$}GOsWA?-_Er0EF7pyrVpomXFkyK8?KR`a<()% zAhTOAr;AE6zP~=+Q%Jx72z0y|a@aT%jEMmt&3bjDG|<4%P-w~~P9a3ef9G$wS}b$D z(12K@9{{7f8N-t#GzJSS*D+ff#_tzqOyeFK9t8yxUp{cfQc zQ%Tn;b!4`}cqr}+C!D2CAMFBsro?3TP&;m}Gj4IM3fX)IKrp|p@5H-5IpUm+e1E(l zF)AEfE;c>#R$u@0-%w7{WA=f0;JO6kNfv!8z%jc3Az)HSg!~fWltbN~0>UzFiE+gz z%WHDVNu9vgzayb3@GasccsE$Yc1u z*J06S<(4LaVHc_Mh2}Z9Ot!rEjH@cK4*=wZbXAH?Hm_hi8|}9IW`vVSrxEtWXH1*O z9BH+`&WCCE>t8L`_CsitNxZl_uzy#hS*p3b8P3^KLQAWUJ5BjV7UU?+ziCfQX~Pti z6epJMj6#~!o$pgvPpm09$S!4@?DNuABia{m4>j==&$l)xeVWsZd5*9(bL?{=d= zWsx$i6iEI+TED!zR0&IOl?8@=zi)-&h?4PrLBx1!9ZoNyC(2awf%Lp7`8Ab-@yrUO zN37-S=B0{lPtR8y+V)<#g?#kV^i*f303i%Xil|IOuntf!3ZN+~LYcN4IZqOZR6X5E zw^~*E{f(P8r`yc6jM}1%ul@OK|15{|TN^H_#a|e2lSb~6Uu}Euvqs{<+P2zq5h;-F z2PQ;E)?_k@q|$=A2Zida+*wSUM)<-Kp8e+^xevRqde|n!l6=Q~QPE9&^W%$jcQ&)l* z$HrbsqYNx(Tm>C<^j78Y{l4546)Ch3NdC<_0?y(65fr9GNcU}5=3+4xhyqRRp>eO9 zU%;MXlMuGh-(2A1j&?7XA^93x=c(v|xjeI96Cv&i&J}Hp{sgk42d!GqFL?{rDQXBx z$uAg9$0wh*-uH3_HKQmN{l&1@`7!X5^P_0^qMh{^(6GP00Ahoy$^pqb+^ftMx?GT= z9SFol_~||@blMjXOFCTvEISl5ty#HJaBJ7%}x586I{=ySdZiv;#;2dJyZY?Zeant;nV$} zXl2%a*rgM)GkD(Lwo%)URl**vBBke|eIkk!nvNGTa>j!Xr-|{vkt~`{fasCb&E%H( z9fJS*1exm5qqH$RpJGvN20sUBO9PSn7s3@q(SJu7iNi7Y!9>(a_vtPK5%>Y4+^*cr z4FEpnO1yvy(-V+{POHVv%rSe*$_@>zkd>8|xQA>&F<1RkR-rUE;58BXjYiAwl?P-O z3iD9%e^)XjT>MV>A%zp=!5VTt7h!w2nmX|@ceEDby3TMp1F_z%V)E4fw)^AWBHkjW zIym&K7!qY;^|^1I`LdNAhdBx^>EZ%PB*(&sjex$c;3u&Ca^y8Gd_luzhpiHnp)UCc^>nk?? z&<6gwV5Cp1?)eg&8hlp+d9lTVP?L!Dt7uuYx22Ey^u9=2g^pb37+nK?VO!?=O+s_L zY;g0qI_0DDD-t-pMGhWMnVXbMJ^N`wz81=|G#)1MEj$<^2Vr}l(>n)IK}aC#+bOg! z@4ylcxPL9rohE2yL_DOA^Pm9o)bf#B`zT$&1L3wqHP5|W;O!NoPp1&}&O)KT;Yz1} z6uG##FcOQYa+^(FEf%B`;UA7HT&e zXph$-s3SDasdZlV;5#4Q-AucnTU0nZ7jhSR6QA6tzJob6HBxC9Q~cWJzvQAcfQ6dd(jLt7%Etp6LOLudG)fP#Z|}K(~^FJUy8b`Jzk{K zQdYN6HX#~=KNv}~*gqi{_F|JHGi40tC-74btWPI$`EC-Yx24KvuJp^L4fyZnUJOpr z$f9qyJ&N9~ANIs_(rxQ^0smw%J(>xj5pOJyZw!*BbdI#0Y!*?P>_LP>TB@HsE49Ka zzgfmHV--<KugO0?Pwbz$@Z3nw)`*6u68g;NblMrJ?O zVie8aglK)P#+V1j_}xyqn<=&VjeLJULz^(<+1in8yzam%|6((H2m4toB~V}m1M>?9 zJub*hncZJ9UJIv_v9WS%<*gehN1aL`_pL`Soxcxs&bv5^NLL?|wCjJZcH^${##Y)P zo6U@jb|3S#KeIHE?2+M6jXpa5@s_lfMy^BK`WfoL26*0XUuW*bdWqVBM&C^qRzS32 zP~3@+3*t-c3gWB4SffAJT-7_bLw;F_G8c_ln#*hG#LkW@muZbND@l=8l}RNR*J-z{ zb+N4E_OU5Mp?>Jr-rD$XKcGA-CQOC^0IEn7RFiuGi0&CmK}TCr0KcwhuW#|)MDa7p zUe4cpvjfy976yaeNSl%Z8g8#wR(x`P{S+Brw~!dbnHY+}%gXE@nRddXmMLwiVcYE# z>Mz=$B1+aZh}8+d>`PRWYN;PAqa=}-CZaLbP_@jnE_iwSYcA?QZJi~>o8?l*ooMd1LXVbV=44# zdo1v4`XkzM$}Iu+JMLG?)jlB0egA1srWXUJ5l*%&Cy>=Y72o%{CSPy7uxfnhG=a+e zQK1-p9D~TLZ`t0IK%koFbxTbFYY%PbQ1OLNm$8zNUI1J^xZI0H;D8}5!KnrbGs^Mc zDic)B!va=`v@vH*h(E#t$`9Rz3__83GeSP@mk&50;r-=}HQ(_1^)b=qxAZ7uJOR87 zAs?;Aa&JTt!WIoe3nN0d;r}##pR{N|+re461+^2^>nGJ|~{)Clrce|RnG*Kt66?6Y=yP@IyMS>4~J3$5p$Nrir zWhaL#EBAtXdNj4Q3Lb`#uNkb3od*K&f;}%@@D1YaF7!<@ z?qbghYHBv++G8&$6CjZjtMh_@xeVW=lqWz-xUJI8X`=+#1ZT!PCD0kG|E*`PQCPJI zv;~!F{I+NN+G8(g%{5lKfuIfos8B7w5ol=ia9TKN_6k-pXZD@5WZ+nh%Xsellb+dj zVONa;y><$tOCzrQK1YIXdw-o;*Mc~pjk3dnj<8MZYSV^Y9U~GSBK>CCRO=u-JPq-M zyadlHK*{fZ28JQiKhZ2vln7t8y7T)Bl?A&&X%!h#yBoR6zHI4z_I)>Nvd*ANcsz^i zINJAuTPNmB?eU;k{0)3Md?%cfKOw7$=q(+v{4yC)~jO7ef- z!};(5%EN47I=Sczh$r@c51tq11AYSo3DfiDfY#y<8(5EmncAOFFcSo^G7zkR*T{p! zbr;3975S)g&)BVg8=im~!G)^wI3g`Dx2iwM9nvGhI|S0KM-1+cOdXsO!xe}YFf}9> zu?b;{V!7~|BCllt>$JkG0EVh)+m%qOiYHb2tlny8Z+TD?BAk+x6s(vbm{#REA6C>J z>qS2TX1Ed2YDd^T12W_`w;RB0IJnRt=`4x13Kt=XX^cUYfKt_avTdrP&a&@Z@Th&UYRs4DYPPQ5tI;-h{cPu&8Gtp zSmkGPo$GXi1~oU?O3fh(qnOkux^ytvGETpAmeNvk+ESo76Tq1&F#y9PU3@x-}M)sGEDSn0O zfR$c!dNuQhQO?|$Y*g{&%=l6zNaZK7PBVyMk2q3yKEy}$7gq^|xu(=S(bBs`i`X(& z=Y4KKHlK2lV+>xN13*%@kooDzaFM=>nTkr+cOVoS2=p{>djCOxZ^WsYnY9G`Jh<(X zY1YPx#x|j}U5e=4!COfT_F9}&QT4Ap72M5wms3pzr7}{`y+w|TWBEbjO}-bAJMqAz z0*uEXU$^;v+&M={$h^r<3^Ci@W3f;Y3YpV$`Nqm{))W8r>_7^?z`do{hO~0YWwX_TM$QPAf6W4Dn*!le z146d#rs`9-aD|)<=4{k^uNnsOhXJkO0zj$BKDni=TJ{CTRwG#pjB z^pzO$w5_xEwAG%+G$!44kI7e#(7{iEjRc`IDYvhCeV>KDZlQ$QbX7{Q3HFb+P|(bcDj zCUymlRX-n05-Ej1fXCk%vuXM4HWNa|xQAq(wTU|mXbi|xV>@yz$rLOxSwVL(tt5dRBmFMQpEM zQ>Fxj*?Eyp(?_#OrtQar2;2i$SGT&O`AC=uoG0NOTXz(Xl!MLHI;K>{8G}%?6hha9 zVNj^xoPq54e({lDJu>K3dwMm9;Hbb0NhkR~tH${hzm!FazJ5LA7#;@C_@C#8`2%v6 zhCo=h!r{0$&?_lzk16Y6V2jEK~L5PcP*`&IEbkFUGiFm>$R zLqA5-6L#}i4^KrwVE8z4;B65)w%d;_Ubw}90y}q&Zzv=xEi^@*V|4z=P%c#@px?1n zxK6*)i3LbN^jlJTSA4%eZ>2`RXS7q4iZ$dz&*IvyEgx)!bMIwNoZ`kC54XO24aCiD zDu`*+ao**=d6n=M^9s2aAwG*By2eankk6F0x97UM*L1p^}b6;W|-_v!OQLBN>xJK|K#0eTG zE7Efl_539Zc*`t_c+62j=M!J6njd9-tL$)FleNVlu8Ro?LsU#BS%@He00$sI!AH8}pTkx{A4X2*feV$rn7 z(I0m(wL3fAGeS?R9ak&uidn9I32L|C|N-ba-b0>*Eh4}^nxv#!K0TRIUX{Fg1-g_^L zcOM~OP$h6Hz=1-$2D`g+K#DAah~NL(j+x#y!ggm#=IWs128Y+^*ZAfGU;9HD#O%>6 z!=nx@BtbQ$i-LmdlfD2+i~t&r>s9>6sDRbdAr*Qv0t9`_QM(A+*^(OZX7{naA21P| zUezzVnp3)lWkD9C!W2PuYlK}OS;QPvm$|B*!Yz7IZ+@Cpf8%>?skJ2^V0jzn(g zITMk6!L$7FMq^Y`T>ROjUd#E70j{4EqK*L%k*Ui%zKu6(J55Q>8P5>`LnD<&n)TX8=L(cRc)IWxO>!<_c#m3D`0ld6Ww z%G0QE=T;a${~#q7)ps1hz1ewZpUIk=SGet}tXhDI-{vDMFBU@7STQd~?cO-Mx4fz=ZlN>Kn|27mtN5iF&^?$YZo?%gK zTe~1oB*{vYC`!(fGa>>aIf-NtNs>i!Do{aCKmk!C=Nu$wN)b>Hkes0eBu6-HZIn{LZt)256tU`?Gwb#i*J|5w)-^Z@v1CnONwT_TK1)aN`1IJ(Qw;NV(< z8e7-n*FRT=N)MX<#wQRlNIv`VD`6(+V$tJd&wgT`8+i4|7#|ov%Q9rDK27}D{8Bi7 zZ{Y!|BT0<0HTfW>}*@=_+CeR3fR@ad&dcB@~kDyBat`WhpsP#Beby0Wy`2-cbz7B~$A2?;y16lXB2!Xv{0mh46!*NDU7du*F6j}2>xNp6)66ilzFh|1W*s7b zqFR2X;d7os|i~EBbbEq?Qg{_q=7x z{22fBu&cv0(jVgw)*C?B|K8}cdtkrr(7cpl44DV2s!Ry5DKNnjJ{NOKSKub%TQfup>Zo{;eTU7rxtZMka^`WqhRhyJV?L}*4;pPpr*QzQyuj7V z6dy<6)XU@-?!d#IWy6-_-*k{SfBYi1u4XDkC)(TKo&aU{$(i29Mx+VSYaY# zO7{qBOz8LPTH79FG1_mDCdzh9NIn_fx!m$Dn&!AdYCycXrUtNQ4EkqT)VU(C|YjN zemTors!!!uKXO~iWfpt#fbwlNgl=x@OeNs0()M}Go0W5P&IT%MhiWs;3 zUT+J|FYM~Jcj`Kp3D>%dji|lIP}h+(uHoZ||1Y+7zS?qLxRM^mh;<(lYrOLDL3R(r z?Z@Ba9ZKpJngQJ1QQ11az8(T5QBvS zWMP|oWp(xNN6_7>;s4W!NIl$k71i<~&;gGWg^X2%{L;qbzkioyRh3H2zP{zXlpcnJ z8GbYmJPsRQU0Ly7uNtWZcL#;>94dFygNF zk|=FCKe=b2-IHDsJO&G$3`B0hDd1Aant8*t0%=&#E97jZ6CiRrsUno3=w;ltXAO3) zqnl_6AOmk*ui1M`I^HiNn6TF_nz946(|(2L<++?UW0aN=u$;ZYjt-Tc?yb<8jAQbl zHb9H`@2s_Cr;+>NJwk!3%#4t%ltm&qiG}r~Jj#$eKRO3=xih}(n;ZV*em^3tMi{jt z@TCWHZO*zCzI5Dm+ZL@>6SMOzea7$z|4eX&Ki_>HvXVIj#IM58*27+r zc4VmvZJi}ywwFRcTd*$PO1(ziLMGXrW!m{p*Sivll6Ciy=EPc&O9A$mJG0vu1JpZ2Ll6z6*=hmLA zydkHggm^Xl37zmdb_e*=mJc0FL1)H&8xwt2_-DkmD&wsd+R!mRs@vHNq7mT=P@@SoZGMe{Wyi3zWp`1Jc#7WLZVgGLpk!@6I@@(| zUMWK5X<$w88v08Zk*Sm|H}IP*9)soD&l`!|Brjblu<_)*UENEsU{S?=*q1wY3G%a7 zn1-NtvMQ#JKJs&H+-HkT!7-r-<+0DH6|ZS*+^Kj -`D~%c`OMch#uscU6Gaa;; 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 literal 8174 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 { const settings = new Settings(); settings.core.engine = 'svg'; settings.core.enableLazyLoading = true; - settings.display.staveProfile = StaveProfile.Tab; settings.display.barsPerRow = 2; return settings; } @@ -39,7 +37,7 @@ describe('TabFingeringPartialUpdate', () => { function createScore(settings: Settings): Score { // the hammer-on crosses from the first into the second system return ScoreLoader.loadAlphaTex( - '\\transpose -4 :4 5.3 5.3 5.3 5.3 | 5.3 5.3 5.3 2.3{h} | 4.3 5.3 5.3 5.3 | 5.3 5.3 5.3 5.3', + '\\track \\staff { tabs } \\transpose -4 :4 5.3 5.3 5.3 5.3 | 5.3 5.3 5.3 2.3{h} | 4.3 5.3 5.3 5.3 | 5.3 5.3 5.3 5.3', settings ); } diff --git a/packages/alphatab/test/visualTests/features/GuitarTabs.test.ts b/packages/alphatab/test/visualTests/features/GuitarTabs.test.ts index 1ae71ca293..56737ed803 100644 --- a/packages/alphatab/test/visualTests/features/GuitarTabs.test.ts +++ b/packages/alphatab/test/visualTests/features/GuitarTabs.test.ts @@ -61,33 +61,53 @@ describe('GuitarTabsTests', () => { ); }); - it('transpose-down', async () => { - // open strings, chords, ties across bars, legato, bends, harmonics, trills and dead notes - // which do not fit on their string after transposing down - const settings = new Settings(); - settings.notation.transpositionPitches = [-4]; - await VisualTestHelper.runVisualTestTex( - ` - \\track \\staff { score tabs } - :4 0.6 3.5{string} 2.4 0.3 | (0.1 0.2 0.3) 3.5 3.5 3.5 | 3.5{t} 2.3{h} 4.3 4.3{b (0 4)} | - 12.6{nh} 12.5{nh} 5.3{tr 7 16} 0.6{x} - `, - 'test-data/visual-tests/guitar-tabs/transpose-down.png', - settings - ); - }); + describe('transpose', () => { + // the original and the transposed track, to compare note and tab placement + async function transposeTest(name: string, semitones: number, music: string, staffMetadata?: string) { + const settings = new Settings(); + settings.notation.transpositionPitches = [0, semitones]; + const staff = `\\staff { score tabs } ${staffMetadata ?? ''}`; + const transposed = `Transposed ${semitones > 0 ? '+' : ''}${semitones}`; + await VisualTestHelper.runVisualTestTex( + `\\track "Original" "Original" ${staff} ${music} \\track "${transposed}" "${transposed}" ${staff} ${music}`, + `test-data/visual-tests/guitar-tabs/transpose-${name}.png`, + settings, + o => { + o.tracks = [0, 1]; + } + ); + } - it('transpose-up', async () => { - // frets beyond the neck after transposing up - const settings = new Settings(); - settings.display.staveProfile = StaveProfile.Tab; - settings.notation.transpositionPitches = [7]; - await VisualTestHelper.runVisualTestTex( - ` - :4 17.1 20.1 (19.2 20.1) 22.2 | 5.6 7.5 0.1 3.3 - `, - 'test-data/visual-tests/guitar-tabs/transpose-up.png', - settings - ); + it('down', async () => + await transposeTest( + 'down', + -4, + `:4 0.6 3.5{string} 2.4 0.3 | (0.1 0.2 0.3) 3.5 3.5 3.5 | 3.5{t} 2.3{h} 4.3 4.3{b (0 4)} | + 12.6{nh} 12.5{nh} 5.3{tr 7 16} 0.6{x}` + )); + it('up', async () => await transposeTest('up', 7, ':4 17.1 20.1 (19.2 20.1) 22.2 | 5.6 7.5 0.1 3.3')); + it('keep-strings', async () => await transposeTest('keep-strings', 2, ':4 3.3 5.2 0.1 12.6')); + it('open-strings', async () => await transposeTest('open-strings', -4, ':4 3.5 2.4 5.3 0.6')); + it('chords', async () => + await transposeTest('chords', -4, ':4 (0.1 0.2) (0.1 0.2 0.3) (3.5 2.4) (0.6 2.5 2.4)')); + it('ties', async () => await transposeTest('ties', -4, ':4 3.5 3.5 3.5 3.5 | -.5 2.4 2.4 -.4')); + it('legato', async () => await transposeTest('legato', -4, ':4 2.3{h} 4.3 2.3{ss} 4.3')); + it('pull-off-to-open', async () => await transposeTest('pull-off-to-open', -2, ':4 6.3{h} 2.3 5.2{h} 2.2')); + it('bends', async () => await transposeTest('bends', -4, ':4 4.3{b (0 4)} 0.1{b (0 4)} 2.2{b (0 4)} 5.3')); + it('natural-harmonics-up', async () => + await transposeTest('natural-harmonics-up', 7, ':4 12.6{nh} 7.5{nh} 5.4{nh} 12.1{nh}')); + it('natural-harmonics-down', async () => + await transposeTest('natural-harmonics-down', -4, ':4 12.6{nh} 7.5{nh} 5.4{nh} 12.1{nh}')); + it('dead-notes', async () => + await transposeTest('dead-notes', -4, ':4 0.6{x} 0.5{x} (0.6{x} 0.5{x} 0.4{x}) 3.5')); + it('trills', async () => await transposeTest('trills', -6, ':2 5.3{tr 7 16} 7.2{tr 8 16}')); + it('ukulele', async () => await transposeTest('ukulele', -6, ':4 2.1 0.2 0.3 0.4', '\\tuning A4 E4 C4 G4')); + it('bass', async () => await transposeTest('bass', -1, ':4 0.3 0.4 3.4 5.4', '\\tuning G2 D2 A1 E1')); + it('capo', async () => await transposeTest('capo', 3, ':4 20.1 15.2 3.3 0.6', '\\capo 2')); + it('grace-notes', async () => await transposeTest('grace-notes', -4, ':4 2.3{ss} {gr ob} 4.3 3.3 3.3')); + it('repeated-bars', async () => + await transposeTest('repeated-bars', -4, ':4 3.5 2.4 0.3 2.4 | 3.5 2.4 0.3 2.4')); + it('multi-voice', async () => + await transposeTest('multi-voice', -4, '\\voice :4 0.1 0.1 0.2 0.2 \\voice :4 1.2 1.2 0.3 0.3')); }); });