diff --git a/Documentation/input/reference/property/playtripletfeel.cshtml b/Documentation/input/reference/property/playtripletfeel.cshtml new file mode 100644 index 000000000..22dfa7ebb --- /dev/null +++ b/Documentation/input/reference/property/playtripletfeel.cshtml @@ -0,0 +1,57 @@ +Title: PlayTripletFeel +JsName: playTripletFeel +DataAttribute: data-play-triplet-feel +Category: Core +Description: Gets or sets whether in the triplet feel should be applied during playback. +Since: 0.9.5 +ShowInSideBar: false +--- + +
+ If this setting is enabled alphaTab will consider the triplet feel during playback not only for display above the notation. +
+ +bool |
+
true
+
+Example - C#
+
+
+
+var settings = Settings.Defaults;
+settings.PlayTripletFeel = false;
+
+
+
+
+Example - JavaScript
+
+
+
+var settings = {
+ playTripletFeel: false
+};
+var api = new alphaTab.platform.javaScript.AlphaTabApi(document.querySelector('#alphaTab'), settings);
+var japi = $('#alphaTab').alphaTab(settings);
+
+
+
+Example - HTML
+
+
+
+<div id="alphaTab" data-play-triplet-feel="true"></div>
+
+
\ No newline at end of file
diff --git a/Phase/Compiler/CopyNewCompiler.bat b/Phase/Compiler/CopyNewCompiler.bat
index 16780a76e..09f3a4adb 100644
--- a/Phase/Compiler/CopyNewCompiler.bat
+++ b/Phase/Compiler/CopyNewCompiler.bat
@@ -1,2 +1,2 @@
taskkill /im:msbuild.exe /f
-xcopy D:\Dev\C#\Projects\Phase.netstandard\Phase.MsBuild\bin\Debug\net471\* . /Y
\ No newline at end of file
+xcopy D:\Dev\CSharp\Phase.netstandard\Phase.MsBuild\bin\Debug\net48\* . /Y
\ No newline at end of file
diff --git a/Phase/Compiler/Microsoft.Build.Framework.dll b/Phase/Compiler/Microsoft.Build.Framework.dll
index 9c692f202..85b367d63 100644
Binary files a/Phase/Compiler/Microsoft.Build.Framework.dll and b/Phase/Compiler/Microsoft.Build.Framework.dll differ
diff --git a/Phase/Compiler/Microsoft.Build.Tasks.Core.dll b/Phase/Compiler/Microsoft.Build.Tasks.Core.dll
index fac36f857..6ba793726 100644
Binary files a/Phase/Compiler/Microsoft.Build.Tasks.Core.dll and b/Phase/Compiler/Microsoft.Build.Tasks.Core.dll differ
diff --git a/Phase/Compiler/Microsoft.Build.Utilities.Core.dll b/Phase/Compiler/Microsoft.Build.Utilities.Core.dll
index 19d33c69d..692696825 100644
Binary files a/Phase/Compiler/Microsoft.Build.Utilities.Core.dll and b/Phase/Compiler/Microsoft.Build.Utilities.Core.dll differ
diff --git a/Phase/Compiler/Microsoft.Build.dll b/Phase/Compiler/Microsoft.Build.dll
index 5b50c7eff..628a3cdab 100644
Binary files a/Phase/Compiler/Microsoft.Build.dll and b/Phase/Compiler/Microsoft.Build.dll differ
diff --git a/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.Workspaces.dll b/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.Workspaces.dll
index 4308c3953..59af42257 100644
Binary files a/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.Workspaces.dll and b/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.Workspaces.dll differ
diff --git a/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.dll b/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.dll
index c48d7ceb6..e4c8010fe 100644
Binary files a/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.dll and b/Phase/Compiler/Microsoft.CodeAnalysis.CSharp.dll differ
diff --git a/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll b/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll
index c861a3a80..b912e4834 100644
Binary files a/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll and b/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll differ
diff --git a/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.dll b/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.dll
index 8ebb96232..14421135d 100644
Binary files a/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.dll and b/Phase/Compiler/Microsoft.CodeAnalysis.VisualBasic.dll differ
diff --git a/Phase/Compiler/Microsoft.CodeAnalysis.Workspaces.dll b/Phase/Compiler/Microsoft.CodeAnalysis.Workspaces.dll
index 545bc452a..a5a5140a9 100644
Binary files a/Phase/Compiler/Microsoft.CodeAnalysis.Workspaces.dll and b/Phase/Compiler/Microsoft.CodeAnalysis.Workspaces.dll differ
diff --git a/Phase/Compiler/Microsoft.CodeAnalysis.dll b/Phase/Compiler/Microsoft.CodeAnalysis.dll
index 6bde7b728..4761ae95d 100644
Binary files a/Phase/Compiler/Microsoft.CodeAnalysis.dll and b/Phase/Compiler/Microsoft.CodeAnalysis.dll differ
diff --git a/Phase/Compiler/Mono.Cecil.Mdb.dll b/Phase/Compiler/Mono.Cecil.Mdb.dll
index 5ecf070ec..18887bcf3 100644
Binary files a/Phase/Compiler/Mono.Cecil.Mdb.dll and b/Phase/Compiler/Mono.Cecil.Mdb.dll differ
diff --git a/Phase/Compiler/Mono.Cecil.Pdb.dll b/Phase/Compiler/Mono.Cecil.Pdb.dll
index e176614a0..680524c21 100644
Binary files a/Phase/Compiler/Mono.Cecil.Pdb.dll and b/Phase/Compiler/Mono.Cecil.Pdb.dll differ
diff --git a/Phase/Compiler/Mono.Cecil.Rocks.dll b/Phase/Compiler/Mono.Cecil.Rocks.dll
index 5d300e844..ddad3a715 100644
Binary files a/Phase/Compiler/Mono.Cecil.Rocks.dll and b/Phase/Compiler/Mono.Cecil.Rocks.dll differ
diff --git a/Phase/Compiler/Mono.Cecil.dll b/Phase/Compiler/Mono.Cecil.dll
index d6e42868c..56b01e9b3 100644
Binary files a/Phase/Compiler/Mono.Cecil.dll and b/Phase/Compiler/Mono.Cecil.dll differ
diff --git a/Phase/Compiler/NLog.dll b/Phase/Compiler/NLog.dll
index 89afd0c5f..9682bd69a 100644
Binary files a/Phase/Compiler/NLog.dll and b/Phase/Compiler/NLog.dll differ
diff --git a/Phase/Compiler/Newtonsoft.Json.dll b/Phase/Compiler/Newtonsoft.Json.dll
index d0aaed9c6..e4a63399d 100644
Binary files a/Phase/Compiler/Newtonsoft.Json.dll and b/Phase/Compiler/Newtonsoft.Json.dll differ
diff --git a/Phase/Compiler/Phase.Core.dll b/Phase/Compiler/Phase.Core.dll
index c5c639471..0518eb479 100644
Binary files a/Phase/Compiler/Phase.Core.dll and b/Phase/Compiler/Phase.Core.dll differ
diff --git a/Phase/Compiler/Phase.Core.pdb b/Phase/Compiler/Phase.Core.pdb
index 9c13816c5..d81a52831 100644
Binary files a/Phase/Compiler/Phase.Core.pdb and b/Phase/Compiler/Phase.Core.pdb differ
diff --git a/Phase/Compiler/Phase.MsBuild.dll b/Phase/Compiler/Phase.MsBuild.dll
index 1d01dadd8..32f737427 100644
Binary files a/Phase/Compiler/Phase.MsBuild.dll and b/Phase/Compiler/Phase.MsBuild.dll differ
diff --git a/Phase/Compiler/Phase.MsBuild.pdb b/Phase/Compiler/Phase.MsBuild.pdb
index 0fdb26450..11da7f720 100644
Binary files a/Phase/Compiler/Phase.MsBuild.pdb and b/Phase/Compiler/Phase.MsBuild.pdb differ
diff --git a/Phase/Compiler/Phase.Translator.dll b/Phase/Compiler/Phase.Translator.dll
index c429828fc..30c31e903 100644
Binary files a/Phase/Compiler/Phase.Translator.dll and b/Phase/Compiler/Phase.Translator.dll differ
diff --git a/Phase/Compiler/Phase.Translator.pdb b/Phase/Compiler/Phase.Translator.pdb
index afeab1b80..abd5b3537 100644
Binary files a/Phase/Compiler/Phase.Translator.pdb and b/Phase/Compiler/Phase.Translator.pdb differ
diff --git a/Phase/Compiler/System.Buffers.dll b/Phase/Compiler/System.Buffers.dll
new file mode 100644
index 000000000..b6d9c7782
Binary files /dev/null and b/Phase/Compiler/System.Buffers.dll differ
diff --git a/Phase/Compiler/System.Collections.Immutable.dll b/Phase/Compiler/System.Collections.Immutable.dll
index 049149f17..900b5ca37 100644
Binary files a/Phase/Compiler/System.Collections.Immutable.dll and b/Phase/Compiler/System.Collections.Immutable.dll differ
diff --git a/Phase/Compiler/System.Memory.dll b/Phase/Compiler/System.Memory.dll
new file mode 100644
index 000000000..bdfc501e9
Binary files /dev/null and b/Phase/Compiler/System.Memory.dll differ
diff --git a/Phase/Compiler/System.Numerics.Vectors.dll b/Phase/Compiler/System.Numerics.Vectors.dll
new file mode 100644
index 000000000..ce46d5be8
Binary files /dev/null and b/Phase/Compiler/System.Numerics.Vectors.dll differ
diff --git a/Phase/Compiler/System.Resources.Extensions.dll b/Phase/Compiler/System.Resources.Extensions.dll
new file mode 100644
index 000000000..73e49c80a
Binary files /dev/null and b/Phase/Compiler/System.Resources.Extensions.dll differ
diff --git a/Phase/Compiler/System.Runtime.CompilerServices.Unsafe.dll b/Phase/Compiler/System.Runtime.CompilerServices.Unsafe.dll
new file mode 100644
index 000000000..315623926
Binary files /dev/null and b/Phase/Compiler/System.Runtime.CompilerServices.Unsafe.dll differ
diff --git a/Phase/Compiler/System.Text.Encoding.CodePages.dll b/Phase/Compiler/System.Text.Encoding.CodePages.dll
index 1e7cf1a9b..d0f7adf9e 100644
Binary files a/Phase/Compiler/System.Text.Encoding.CodePages.dll and b/Phase/Compiler/System.Text.Encoding.CodePages.dll differ
diff --git a/Phase/Compiler/System.Threading.Tasks.Dataflow.dll b/Phase/Compiler/System.Threading.Tasks.Dataflow.dll
index 7567471e1..a6816d4a8 100644
Binary files a/Phase/Compiler/System.Threading.Tasks.Dataflow.dll and b/Phase/Compiler/System.Threading.Tasks.Dataflow.dll differ
diff --git a/Phase/Compiler/System.Threading.Tasks.Extensions.dll b/Phase/Compiler/System.Threading.Tasks.Extensions.dll
index a1234ce81..e059050bb 100644
Binary files a/Phase/Compiler/System.Threading.Tasks.Extensions.dll and b/Phase/Compiler/System.Threading.Tasks.Extensions.dll differ
diff --git a/Samples/CSharp/AlphaTab.Samples.Player/AlphaTab.Samples.Player.csproj b/Samples/CSharp/AlphaTab.Samples.Player/AlphaTab.Samples.Player.csproj
index 7801c3c94..f801d99c6 100644
--- a/Samples/CSharp/AlphaTab.Samples.Player/AlphaTab.Samples.Player.csproj
+++ b/Samples/CSharp/AlphaTab.Samples.Player/AlphaTab.Samples.Player.csproj
@@ -1,6 +1,6 @@
- net472
+ net48
Exe
@@ -15,4 +15,4 @@
-
\ No newline at end of file
+
diff --git a/Samples/CSharp/AlphaTab.Samples.PngDump/AlphaTab.Samples.PngDump.csproj b/Samples/CSharp/AlphaTab.Samples.PngDump/AlphaTab.Samples.PngDump.csproj
index 5176de37f..580721b70 100644
--- a/Samples/CSharp/AlphaTab.Samples.PngDump/AlphaTab.Samples.PngDump.csproj
+++ b/Samples/CSharp/AlphaTab.Samples.PngDump/AlphaTab.Samples.PngDump.csproj
@@ -1,6 +1,6 @@
- net472
+ net48
Exe
diff --git a/Samples/CSharp/AlphaTab.Samples.ScoreDump/AlphaTab.Samples.ScoreDump.csproj b/Samples/CSharp/AlphaTab.Samples.ScoreDump/AlphaTab.Samples.ScoreDump.csproj
index 5176de37f..580721b70 100644
--- a/Samples/CSharp/AlphaTab.Samples.ScoreDump/AlphaTab.Samples.ScoreDump.csproj
+++ b/Samples/CSharp/AlphaTab.Samples.ScoreDump/AlphaTab.Samples.ScoreDump.csproj
@@ -1,6 +1,6 @@
- net472
+ net48
Exe
diff --git a/Samples/CSharp/AlphaTab.Samples.WinForms/AlphaTab.Samples.WinForms.csproj b/Samples/CSharp/AlphaTab.Samples.WinForms/AlphaTab.Samples.WinForms.csproj
index 4753f4ab9..7e259c9b0 100644
--- a/Samples/CSharp/AlphaTab.Samples.WinForms/AlphaTab.Samples.WinForms.csproj
+++ b/Samples/CSharp/AlphaTab.Samples.WinForms/AlphaTab.Samples.WinForms.csproj
@@ -1,6 +1,6 @@
- net472
+ net48
WinExe
true
@@ -20,4 +20,4 @@
-
\ No newline at end of file
+
diff --git a/Samples/CSharp/AlphaTab.Samples.Wpf/AlphaTab.Samples.Wpf.csproj b/Samples/CSharp/AlphaTab.Samples.Wpf/AlphaTab.Samples.Wpf.csproj
index 3e08635e9..a8d14dc15 100644
--- a/Samples/CSharp/AlphaTab.Samples.Wpf/AlphaTab.Samples.Wpf.csproj
+++ b/Samples/CSharp/AlphaTab.Samples.Wpf/AlphaTab.Samples.Wpf.csproj
@@ -1,6 +1,6 @@
- net472
+ net48
WinExe
true
@@ -12,7 +12,7 @@
-
+
@@ -37,4 +37,4 @@
-
\ No newline at end of file
+
diff --git a/Source/AlphaTab.CSharp/AlphaTab.CSharp.csproj b/Source/AlphaTab.CSharp/AlphaTab.CSharp.csproj
index ad5ff8c6c..ccf66ef6b 100644
--- a/Source/AlphaTab.CSharp/AlphaTab.CSharp.csproj
+++ b/Source/AlphaTab.CSharp/AlphaTab.CSharp.csproj
@@ -3,13 +3,13 @@
AlphaTab
AlphaTab
AlphaTab
- netstandard2.0;net472
+ netstandard2.0;net48
true
$(OutDir)$(AssemblyName).xml
$(NoWarn);0162
-
+
true
true
true
@@ -28,7 +28,7 @@
-
+
@@ -61,4 +61,4 @@
-
\ No newline at end of file
+
diff --git a/Source/AlphaTab.CSharp/Environment.cs b/Source/AlphaTab.CSharp/Environment.cs
index 506551850..b15c8696c 100644
--- a/Source/AlphaTab.CSharp/Environment.cs
+++ b/Source/AlphaTab.CSharp/Environment.cs
@@ -8,7 +8,7 @@ internal partial class Environment
private static void PlatformInit()
{
RenderEngines["svg"] = new RenderEngineFactory(true, () => new CssFontSvgCanvas());
-#if NET472
+#if NET48
RenderEngines["gdi"] = new RenderEngineFactory(true, () => new GdiCanvas());
#endif
RenderEngines["skia"] = new RenderEngineFactory(true, () => new SkiaCanvas());
diff --git a/Source/AlphaTab.CSharp/IO/ZipFile.cs b/Source/AlphaTab.CSharp/IO/ZipFile.cs
index a621e555e..5426c8dcb 100644
--- a/Source/AlphaTab.CSharp/IO/ZipFile.cs
+++ b/Source/AlphaTab.CSharp/IO/ZipFile.cs
@@ -11,7 +11,7 @@ internal partial class ZipFile
///
public void Load(IReadable s)
{
-#if NET472 || NETSTANDARD2_0
+#if NET48 || NETSTANDARD2_0
using (var zipArchive = new System.IO.Compression.ZipArchive(ReadableStream.Create(s),
System.IO.Compression.ZipArchiveMode.Read))
{
@@ -57,7 +57,7 @@ public void Load(IReadable s)
}
}
}
-
+
}
#endif
}
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/GdiCanvas.cs b/Source/AlphaTab.CSharp/Platform/CSharp/GdiCanvas.cs
index b608bde9b..152f9b90b 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/GdiCanvas.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/GdiCanvas.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using AlphaTab.Rendering;
using AlphaTab.Rendering.Glyphs;
using AlphaTab.Rendering.Utils;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs
index d8027e785..d5382f387 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabControl.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabLayoutPanel.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabLayoutPanel.cs
index 7878fd8d8..7fcf25728 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabLayoutPanel.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/AlphaTabLayoutPanel.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/ControlContainer.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/ControlContainer.cs
index c1b35facc..d102f22f2 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/ControlContainer.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/ControlContainer.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System;
using System.Drawing;
using System.Windows.Forms;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/SkiaUtil.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/SkiaUtil.cs
index 18e3c01d2..bbbf2dfe1 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/SkiaUtil.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/SkiaUtil.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.Drawing;
using System.Drawing.Imaging;
using SkiaSharp;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsMouseEventArgs.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsMouseEventArgs.cs
index 75bf967bd..a63b0182f 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsMouseEventArgs.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsMouseEventArgs.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.Windows.Forms;
using AlphaTab.UI;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsUiFacade.cs b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsUiFacade.cs
index 7c37b7bb8..0b5a52539 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsUiFacade.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/WinForms/WinFormsUiFacade.cs
@@ -1,7 +1,7 @@
using AlphaTab.Importer;
using AlphaTab.Model;
-#if NET472
+#if NET48
using System;
using System.Collections.Concurrent;
using System.Drawing;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs
index 87fa723c7..d84b946a9 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTab.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTabLayoutPanel.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTabLayoutPanel.cs
index ca36ce0c7..805930321 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTabLayoutPanel.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/AlphaTabLayoutPanel.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.Windows;
using System.Windows.Controls;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/FrameworkElementContainer.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/FrameworkElementContainer.cs
index b53c32c3b..75900c85c 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/FrameworkElementContainer.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/FrameworkElementContainer.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System;
using System.Windows;
using System.Windows.Controls;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/GdiImageSource.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/GdiImageSource.cs
index e665b9c63..b8eb53a9f 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/GdiImageSource.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/GdiImageSource.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Media;
@@ -6,7 +6,7 @@
namespace AlphaTab.Platform.CSharp.Wpf
{
- internal class GdiImageSource
+ internal class GdiImageSource
{
public static BitmapSource Create(Bitmap image)
{
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/NAudioSynthOutput.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/NAudioSynthOutput.cs
index fa075eec5..581e9e76a 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/NAudioSynthOutput.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/NAudioSynthOutput.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System;
using AlphaTab.Audio.Synth;
using AlphaTab.Audio.Synth.Ds;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/SkImageSource.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/SkImageSource.cs
index 5fb54ffcc..f026bb23d 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/SkImageSource.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/SkImageSource.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
@@ -6,7 +6,7 @@
namespace AlphaTab.Platform.CSharp.Wpf
{
- internal class SkImageSource
+ internal class SkImageSource
{
public static BitmapSource Create(object data)
{
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfMouseEventArgs.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfMouseEventArgs.cs
index 51e7e3c5e..285beb3b5 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfMouseEventArgs.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfMouseEventArgs.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System.Windows.Input;
using AlphaTab.UI;
diff --git a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfUiFacade.cs b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfUiFacade.cs
index 67abfc6c7..a13209b7b 100644
--- a/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfUiFacade.cs
+++ b/Source/AlphaTab.CSharp/Platform/CSharp/Wpf/WpfUiFacade.cs
@@ -1,4 +1,4 @@
-#if NET472
+#if NET48
using System;
using System.Collections.Concurrent;
using System.IO;
diff --git a/Source/AlphaTab.JavaScript/AlphaTab.JavaScript.csproj b/Source/AlphaTab.JavaScript/AlphaTab.JavaScript.csproj
index 5285910e6..b37bd7d1c 100644
--- a/Source/AlphaTab.JavaScript/AlphaTab.JavaScript.csproj
+++ b/Source/AlphaTab.JavaScript/AlphaTab.JavaScript.csproj
@@ -3,7 +3,7 @@
AlphaTab.JavaScript
AlphaTab
AlphaTab.JavaScript
- net472
+ net48
$(NoWarn);0626;0824
$(DefineConstants);JavaScript
@@ -21,4 +21,4 @@
-
\ No newline at end of file
+
diff --git a/Source/AlphaTab.JavaScript/Settings.cs b/Source/AlphaTab.JavaScript/Settings.cs
index 94ebb3650..f40beeade 100644
--- a/Source/AlphaTab.JavaScript/Settings.cs
+++ b/Source/AlphaTab.JavaScript/Settings.cs
@@ -151,6 +151,7 @@ public dynamic ToJson()
json.includeNoteBounds = IncludeNoteBounds;
+ json.playTripletFeel = PlayTripletFeel;
json.vibrato = Platform.Platform.NewObject();
json.noteSlightAmplitude = Vibrato.NoteSlightAmplitude;
json.noteWideAmplitude = Vibrato.NoteWideAmplitude;
@@ -521,6 +522,15 @@ public static void FillFromJson(Settings settings, dynamic json, FastDictionary<
settings.IncludeNoteBounds = (bool)dataAttributes["includeNoteBounds"];
}
+ if (Platform.Platform.JsonExists(json, "playTripletFeel"))
+ {
+ settings.PlayTripletFeel = json.playTripletFeel;
+ }
+ else if (dataAttributes != null && dataAttributes.ContainsKey("playTripletFeel"))
+ {
+ settings.PlayTripletFeel = (bool)dataAttributes["playTripletFeel"];
+ }
+
if (Platform.Platform.JsonExists(json, "vibrato"))
{
var vibrato = json.vibrato;
diff --git a/Source/AlphaTab.Test.CSharp/AlphaTab.Test.CSharp.csproj b/Source/AlphaTab.Test.CSharp/AlphaTab.Test.CSharp.csproj
index 5344faa42..441628015 100644
--- a/Source/AlphaTab.Test.CSharp/AlphaTab.Test.CSharp.csproj
+++ b/Source/AlphaTab.Test.CSharp/AlphaTab.Test.CSharp.csproj
@@ -2,7 +2,7 @@
AlphaTab.Test.CSharp
AlphaTab.Test.CSharp
- net472
+ net48
AlphaTab.Test.CSharp
$(NoWarn);0626;0824
true
@@ -36,4 +36,4 @@
-
\ No newline at end of file
+
diff --git a/Source/AlphaTab.Test.Js/AlphaTab.Test.Js.csproj b/Source/AlphaTab.Test.Js/AlphaTab.Test.Js.csproj
index 2b6d44bc0..39c75aeee 100644
--- a/Source/AlphaTab.Test.Js/AlphaTab.Test.Js.csproj
+++ b/Source/AlphaTab.Test.Js/AlphaTab.Test.Js.csproj
@@ -2,7 +2,7 @@
AlphaTab.Test.Js
AlphaTab.Test.Js
- net472
+ net48
$(NoWarn);0626;0824
{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
@@ -37,4 +37,4 @@
-
\ No newline at end of file
+
diff --git a/Source/AlphaTab.Test.Js/test/alphaTab.tests.specs.js b/Source/AlphaTab.Test.Js/test/alphaTab.tests.specs.js
index 6eadf257f..d9afaf41b 100644
--- a/Source/AlphaTab.Test.Js/test/alphaTab.tests.specs.js
+++ b/Source/AlphaTab.Test.Js/test/alphaTab.tests.specs.js
@@ -31,6 +31,11 @@ describe("alphaTab.test.audio.MidiFileGeneratorTest", function() {
__instance.testBendMultiPoint();
done();
});
+ it("testTripletFeel", function(done) {
+ alphaTab.test.TestPlatform.Done = done;
+ __instance.testTripletFeel();
+ done();
+ });
});
describe("alphaTab.test.audio.MidiPlaybackControllerTest", function() {
var __instance = new alphaTab.test.audio.MidiPlaybackControllerTest();
diff --git a/Source/AlphaTab.Test/Audio/MidiFileGeneratorTest.cs b/Source/AlphaTab.Test/Audio/MidiFileGeneratorTest.cs
index 2bd62bf88..bd3c96d50 100644
--- a/Source/AlphaTab.Test/Audio/MidiFileGeneratorTest.cs
+++ b/Source/AlphaTab.Test/Audio/MidiFileGeneratorTest.cs
@@ -60,7 +60,6 @@ public void TestBend()
{
var tex = ":4 15.6{b(0 4)} 15.6";
var score = ParseTex(tex);
-
Assert.AreEqual(1, score.Tracks.Count);
Assert.AreEqual(1, score.Tracks[0].Staves[0].Bars.Count);
Assert.AreEqual(1, score.Tracks[0].Staves[0].Bars[0].Voices.Count);
@@ -369,5 +368,90 @@ public void TestBendMultiPoint()
Assert.AreEqual(expectedEvents.Length, handler.MidiEvents.Count);
}
+
+ [TestMethod]
+ public void TestTripletFeel()
+ {
+ var tex = "\\ts 2 4 \\tf t8 3.2.8*4 | \\tf t16 3.2.16*8 | \\tf d8 3.2.8*4 | \\tf d16 3.2.16*8 | \\tf s8 3.2.8*4 | \\tf s16 3.2.16*8";
+ var score = ParseTex(tex);
+
+ var expectedPlaybackStartTimes = new FastList
+ {
+ // @formatter:off
+ 0, 480, 960, 1440,
+ 0, 240, 480, 720, 960, 1200, 1440, 1680,
+ 0, 480, 960, 1440,
+ 0, 240, 480, 720, 960, 1200, 1440, 1680,
+ 0, 480, 960, 1440,
+ 0, 240, 480, 720, 960, 1200, 1440, 1680
+ // @formatter:on
+ };
+ var expectedPlaybackDurations = new FastList
+ {
+ // @formatter:off
+ 480, 480, 480, 480,
+ 240, 240, 240, 240, 240, 240, 240, 240,
+ 480, 480, 480, 480,
+ 240, 240, 240, 240, 240, 240, 240, 240,
+ 480, 480, 480, 480,
+ 240, 240, 240, 240, 240, 240, 240, 240
+ // @formatter:on
+ };
+ var actualPlaybackStartTimes = new FastList();
+ var actualPlaybackDurations = new FastList();
+
+ var beat = score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0];
+ while (beat != null)
+ {
+ actualPlaybackStartTimes.Add(beat.PlaybackStart);
+ actualPlaybackDurations.Add(beat.PlaybackDuration);
+ beat = beat.NextBeat;
+ }
+
+ Assert.AreEqual(string.Join(",", expectedPlaybackStartTimes), string.Join(",", actualPlaybackStartTimes));
+ Assert.AreEqual(string.Join(",", expectedPlaybackDurations), string.Join(",", actualPlaybackDurations));
+
+ var expectedMidiStartTimes = new FastList
+ {
+ // @formatter:off
+ 0, 640, 960, 1600,
+ 1920, 2240, 2400, 2720, 2880, 3200, 3360, 3680,
+ 3840, 4560, 4800, 5520,
+ 5760, 6120, 6240, 6600, 6720, 7080, 7200, 7560,
+ 7680, 7920, 8640, 8880,
+ 9600, 9720, 10080, 10200, 10560, 10680, 11040, 11160
+ // @formatter:on
+ };
+ var expectedMidiDurations = new FastList
+ {
+ // @formatter:off
+ 640, 320, 640, 320,
+ 320, 160, 320, 160, 320, 160, 320 ,160,
+ 720, 240, 720, 240,
+ 360, 120, 360, 120, 360, 120, 360, 120,
+ 240, 720, 240, 720,
+ 120, 360, 120, 360, 120, 360, 120, 360
+ // @formatter:on
+ };
+ var actualMidiStartTimes = new FastList();
+ var actualMidiDurations = new FastList();
+
+ var handler = new FlatMidiEventGenerator();
+ var generator = new MidiFileGenerator(score, null, handler);
+ generator.Generate();
+
+ foreach (var midiEvent in handler.MidiEvents)
+ {
+ if (midiEvent is FlatMidiEventGenerator.NoteEvent)
+ {
+ var noteEvent = (FlatMidiEventGenerator.NoteEvent)midiEvent;
+ actualMidiStartTimes.Add(noteEvent.Tick);
+ actualMidiDurations.Add(noteEvent.Length);
+ }
+ }
+
+ Assert.AreEqual(string.Join(",", expectedMidiStartTimes), string.Join(",", actualMidiStartTimes));
+ Assert.AreEqual(string.Join(",", expectedMidiDurations), string.Join(",", actualMidiDurations));
+ }
}
}
diff --git a/Source/AlphaTab/Audio/Generator/MidiFileGenerator.cs b/Source/AlphaTab/Audio/Generator/MidiFileGenerator.cs
index 01e7d77e4..b35a74046 100644
--- a/Source/AlphaTab/Audio/Generator/MidiFileGenerator.cs
+++ b/Source/AlphaTab/Audio/Generator/MidiFileGenerator.cs
@@ -229,13 +229,36 @@ private void GenerateVoice(Voice voice, int barStartTick, Bar realBar)
}
}
+ private TripletFeelDurations _currentTripletFeel;
+
private void GenerateBeat(Beat beat, int barStartTick, Bar realBar)
{
// TODO: take care of tripletfeel
var beatStart = beat.PlaybackStart;
- var audioDuration = beat.Voice.Bar.IsEmpty
- ? beat.Voice.Bar.MasterBar.CalculateDuration()
- : beat.PlaybackDuration;
+ var audioDuration = beat.PlaybackDuration;
+
+ if (beat.Voice.Bar.IsEmpty)
+ {
+ audioDuration = beat.Voice.Bar.MasterBar.CalculateDuration();
+ }
+ else if (beat.Voice.Bar.MasterBar.TripletFeel != TripletFeel.NoTripletFeel && (_settings == null || _settings.PlayTripletFeel))
+ {
+ if (_currentTripletFeel != null)
+ {
+ beatStart -= _currentTripletFeel.SecondBeatStartOffset;
+ audioDuration = _currentTripletFeel.SecondBeatDuration;
+ _currentTripletFeel = null;
+ }
+ else
+ {
+ _currentTripletFeel = CalculateTripletFeelInfo(beatStart, audioDuration, beat);
+ if (_currentTripletFeel != null)
+ {
+ audioDuration = _currentTripletFeel.FirstBeatDuration;
+ }
+ }
+ }
+
var beatLookup = new BeatTickLookup();
beatLookup.Start = barStartTick + beatStart;
@@ -316,6 +339,92 @@ private void GenerateBeat(Beat beat, int barStartTick, Bar realBar)
}
}
+ private class TripletFeelDurations
+ {
+ public int FirstBeatDuration { get; set; }
+ public int SecondBeatStartOffset { get; set; }
+ public int SecondBeatDuration { get; set; }
+ }
+
+ private TripletFeelDurations CalculateTripletFeelInfo(int beatStart, int audioDuration, Beat beat)
+ {
+ Duration initialDuration;
+ switch (beat.Voice.Bar.MasterBar.TripletFeel)
+ {
+ case TripletFeel.Triplet8th:
+ case TripletFeel.Dotted8th:
+ case TripletFeel.Scottish8th:
+ initialDuration = Duration.Eighth;
+ break;
+ case TripletFeel.Triplet16th:
+ case TripletFeel.Dotted16th:
+ case TripletFeel.Scottish16th:
+ initialDuration = Duration.Sixteenth;
+ break;
+ default:
+ // not possible
+ return null;
+ }
+
+ var interval = initialDuration.ToTicks();
+
+ // it must be a plain note with the expected duration
+ // without dots, triplets, grace notes etc.
+ if (audioDuration != interval)
+ {
+ return null;
+ }
+
+ // check if the beat is aligned in respect to the duration
+ // e.g. the eighth notes on a 4/4 time signature must start exactly on the following
+ // times to get a triplet feel applied
+ // 0 480 960 1440 1920 2400 2880 3360
+ if ((beatStart % interval) != 0)
+ {
+ return null;
+ }
+
+ // ensure next beat matches spec
+ if (beat.NextBeat == null || beat.NextBeat.Voice != beat.Voice || beat.PlaybackDuration != interval)
+ {
+ return null;
+ }
+
+ // looks like we have a triplet feel combination start here!
+ var durations = new TripletFeelDurations();
+ switch (beat.Voice.Bar.MasterBar.TripletFeel)
+ {
+ case TripletFeel.Triplet8th:
+ durations.FirstBeatDuration = MidiUtils.ApplyTuplet(Duration.Quarter.ToTicks(), 3, 2);
+ durations.SecondBeatDuration = MidiUtils.ApplyTuplet(Duration.Eighth.ToTicks(), 3, 2);
+ break;
+ case TripletFeel.Dotted8th:
+ durations.FirstBeatDuration = MidiUtils.ApplyDot(Duration.Eighth.ToTicks(), false);
+ durations.SecondBeatDuration = Duration.Sixteenth.ToTicks();
+ break;
+ case TripletFeel.Scottish8th:
+ durations.FirstBeatDuration = Duration.Sixteenth.ToTicks();
+ durations.SecondBeatDuration = MidiUtils.ApplyDot(Duration.Eighth.ToTicks(), false);
+ break;
+ case TripletFeel.Triplet16th:
+ durations.FirstBeatDuration = MidiUtils.ApplyTuplet(Duration.Eighth.ToTicks(), 3, 2);
+ durations.SecondBeatDuration = MidiUtils.ApplyTuplet(Duration.Sixteenth.ToTicks(), 3, 2);
+ break;
+ case TripletFeel.Dotted16th:
+ durations.FirstBeatDuration = MidiUtils.ApplyDot(Duration.Sixteenth.ToTicks(), false);
+ durations.SecondBeatDuration = Duration.ThirtySecond.ToTicks();
+ break;
+ case TripletFeel.Scottish16th:
+ durations.FirstBeatDuration = Duration.ThirtySecond.ToTicks();
+ durations.SecondBeatDuration = MidiUtils.ApplyDot(Duration.Sixteenth.ToTicks(), false);
+ break;
+ }
+
+ // calculate the number of ticks the second beat can start earlier
+ durations.SecondBeatStartOffset = audioDuration - durations.FirstBeatDuration;
+ return durations;
+ }
+
private void GenerateNote(Note note, int beatStart, int beatDuration, int[] brushInfo)
{
var track = note.Beat.Voice.Bar.Staff.Track;
@@ -916,7 +1025,7 @@ private void GenerateWhammy(Beat beat, int noteStart, MidiNoteDuration noteDurat
break;
case BendStyle.Fast:
var whammyDuration = Math.Min(duration,
- MidiUtils.MillisToTicks(_settings.SongBookBendDuration, _currentTempo));
+ MidiUtils.MillisToTicks(_settings.SongBookBendDuration, _currentTempo));
GenerateSongBookWhammyOrBend(noteStart,
channel,
duration,
@@ -944,7 +1053,7 @@ private void GenerateWhammy(Beat beat, int noteStart, MidiNoteDuration noteDurat
break;
case BendStyle.Fast:
var whammyDuration = Math.Min(duration,
- MidiUtils.MillisToTicks(_settings.SongBookDipDuration, _currentTempo));
+ MidiUtils.MillisToTicks(_settings.SongBookDipDuration, _currentTempo));
GenerateSongBookWhammyOrBend(noteStart,
channel,
duration,
@@ -981,7 +1090,7 @@ private void GenerateWhammy(Beat beat, int noteStart, MidiNoteDuration noteDurat
_handler.AddBend(track.Index, noteStart, (byte)channel, (int)preDiveValue);
var whammyDuration = Math.Min(duration,
- MidiUtils.MillisToTicks(_settings.SongBookBendDuration, _currentTempo));
+ MidiUtils.MillisToTicks(_settings.SongBookBendDuration, _currentTempo));
GenerateSongBookWhammyOrBend(noteStart,
channel,
duration,
diff --git a/Source/AlphaTab/Settings.cs b/Source/AlphaTab/Settings.cs
index 9c1e60cf8..24784662a 100644
--- a/Source/AlphaTab/Settings.cs
+++ b/Source/AlphaTab/Settings.cs
@@ -126,6 +126,11 @@ public partial class Settings
///
public VibratoPlaybackSettings Vibrato { get; set; }
+ ///
+ /// Gets or sets whether the triplet feel should be applied/played during audio playback.
+ ///
+ public bool PlayTripletFeel { get; set; }
+
///
/// Gets or sets the height for slurs. The factor is multiplied with the a logarithmic distance
/// between slur start and end.
@@ -275,6 +280,8 @@ public static Settings Defaults
settings.Vibrato.BeatSlightLength = 240;
settings.Vibrato.BeatWideLength = 240;
+ settings.PlayTripletFeel = true;
+
settings.SongBookBendDuration = 75;
settings.SongBookDipDuration = 150;
settings.IncludeNoteBounds = false;