diff --git a/docs/alphatex/_bar-metadata.mdx b/docs/alphatex/_bar-metadata.mdx index 3541a73..865b9f3 100644 --- a/docs/alphatex/_bar-metadata.mdx +++ b/docs/alphatex/_bar-metadata.mdx @@ -720,3 +720,170 @@ This tag allows specifying the sustain pedal relative to the bar. The sustain pe `} +## `\voiceMode` + +```plain title="Syntax" +\voiceMode mode +``` + +**Description:** Changes the mode how alphaTab should treat voices when adding `\voice`. + +You can either choose to write voice-by-voice where each voice has all bars defined. +You write bar-by-bar where a new voice is only added to the current bar. + + +**Parameters:** + +| Name | Description | Type | Required | +|------|-------------|------|----------| +| `mode` | The mode which should be active | `staffWise\|barWise` | yes | + +**Parameter Values:** + +Following parameters have value limitations + +| Name | Values | +|------|--------| +| `mode` | | + +**Example:** + +{` +\\title "Staff Wise Voices" +\\voiceMode staffWise +// Voice 1 +\\voice + // Bar 1 Voice 1 + C4*4 | + // Bar 2 Voice 1 + C5*4 | + // Bar 3 Voice 1 + C6*4 +// Voice 2 +\\voice + // Bar 1 Voice 2 + C3*4 | + // Bar 2 Voice 2 + C4*4 | + // Bar 3 Voice 2 + C5 * 4 + +`} +{` +\\title "Bar Wise Voices" +\\voiceMode barWise +// Bar 1 + // Bar 1 Voice 1 + \\voice + C4*4 + // Bar 1 Voice 2 + \\voice + C3*4 +| +// Bar 2 + // Bar 2 Voice 1 + \\voice + C5*4 + // Bar 2 Voice 2 + \\voice + C4*4 +| +// Bar 3 + // Bar 3 Voice 1 + \\voice + C6*4 + // Bar 3 Voice 2 + \\voice + C5 * 4 + +`} + +## `\barNumberDisplay` + +```plain title="Syntax" +\barNumberDisplay mode +``` + +**Description:** Sets the display mode for bar numbers. + +**Parameters:** + +| Name | Description | Type | Required | +|------|-------------|------|----------| +| `mode` | The mode to use | `allBars\|firstOfSystem\|hide` | yes | + +**Parameter Values:** + +Following parameters have value limitations + +| Name | Values | +|------|--------| +| `mode` | | + +**Example:** + +{` +\\defaultBarNumberDisplay hide +\\track { defaultsystemslayout 3 } + C4.1 | \\barNumberDisplay allBars C4.1 | C4.1 | + \\barNumberDisplay firstOfSystem C4.1 | \\barNumberDisplay firstOfSystem C4.1 | C4.1 + +`} +{` +\\defaultBarNumberDisplay firstOfSystem +\\track { defaultsystemslayout 3 } + C4.1 | \\barNumberDisplay allBars C4.1 | C4.1 | + \\barNumberDisplay hide C4.1 | C4.1 | C4.1 + +`} + +## `\beaming` + +```plain title="Syntax" +\beaming (duration groups) +``` + +**Description:** Defines a custom beaming rule defining how beams of certain durations should be beamed. + +To define how beats should be beamed we need 2 parts: + +1. A duration with which we splitup the bars +2. A list of group sizes defining how many split-parts should be beamed together. + +The beaming rules go hand-in-hand with the time signature as the rules need to properly +define the groups for the whole beat. + +Let's take a simple example of a 4/4 time signature. If we want to ensure that the beats within the quarter notes are +beamed together we can write variants like this: + +a. `\beaming (4 1 1 1 1)` +b. `\beaming (8 2 2 2 2)` +c. `\beaming (16 4 4 4 4)` + +We slice the bar into 4, 8 or 16 parts. Then we add "groups" to those parts. If two beats start in the same group, they can be beamed together. +Simple as that. + +There are some common guidelines on how beaming "should be done" and alphaTab ships a wide range of defaults. But in case of more specialized time signatures, +you can also customize the beaming as you need by slicing the bar and grouping the beats as needed. + + +**Parameters:** + +| Name | Description | Type | Required | +|------|-------------|------|----------| +| `duration` | The note duration defining the smallest group size | `Number` | yes | +| `groups` | For every group the number of notes contained in the group. | `Number[]` | no | + +**Example:** + +{` +\\ts (4 4) +\\beaming (8 4 2 2) +C4.8 * 8 | + +\\ts (4 4) +\\beaming (8 4 4) +C4.8 * 8 + +`} + diff --git a/docs/alphatex/_beat-properties.mdx b/docs/alphatex/_beat-properties.mdx index 8b71cf2..2441518 100644 --- a/docs/alphatex/_beat-properties.mdx +++ b/docs/alphatex/_beat-properties.mdx @@ -889,7 +889,7 @@ C4 {balance 0} D4 E4 {balance 16} F4 ## `tp` ```plain title="Syntax" -tp speed +tp (marks style) ``` **Description:** Add a tremolo picking to the beat. @@ -898,7 +898,8 @@ tp speed | Name | Description | Type | Required | |------|-------------|------|----------| -| `speed` | The tremolo picking speed | `8\|16\|32` | yes | +| `marks` | The number of tremolo marks | `Number` | yes | +| `style` | The tremolo style | `default\|buzzRoll` | no | **Parameter Values:** @@ -906,12 +907,19 @@ Following parameters have value limitations | Name | Values | |------|--------| -| `speed` | | +| `marks` | | +| `style` | | **Example:** {` -3.3{tp 8} 3.3{tp 16} 3.3{tp 32} +3.3{tp 1} 3.3{tp 2} 3.3{tp 3} + +`} +{` +\\title "Buzz Rolls" +3.3{tp (0 buzzRoll)} // no audio +3.3{tp (1 buzzRoll)} // 8th notes tremolo shown as buzzroll `} diff --git a/docs/alphatex/_score-metadata.mdx b/docs/alphatex/_score-metadata.mdx index f00e5e4..a6db816 100644 --- a/docs/alphatex/_score-metadata.mdx +++ b/docs/alphatex/_score-metadata.mdx @@ -762,3 +762,189 @@ Following parameters have value limitations `} +## `\extendBarLines` + +```plain title="Syntax" +\extendBarLines () +``` + +**Description:** Extend the bar lines across staves in the same system. + +**Example:** + +{` +\\extendBarLines +\\track "Piano1" + \\staff {score} +\\instrument piano + C4 D4 E4 F4 + \\staff {score} + \\clef f4 C3 D3 E3 F3 +\\track "Piano2" + \\staff {score} +\\instrument piano + C4 D4 E4 F4 +\\track "Flute 1" + \\staff { score } +\\instrument flute + C4 D4 E4 F4 +\\track "Flute 2" + \\staff { score } +\\instrument flute + \\clef f4 C3 D3 E3 F3 +\\track "Guitar 1" + \\staff { score tabs } + 0.3.4 2.3.4 5.3.4 7.3.4 + +`} + +## `\chordDiagramsInScore` + +```plain title="Syntax" +\chordDiagramsInScore visibility +``` + +**Description:** Configures whether chord diagrams are shown inline in the score.. + +**Parameters:** + +| Name | Description | Type | Required | +|------|-------------|------|----------| +| `visibility` | The visibility of the diagrams | `true\|false` | no `true` | + +**Parameter Values:** + +Following parameters have value limitations + +| Name | Values | +|------|--------| +| `visibility` | | + +**Example:** + +{` +\\chordDiagramsInScore +\\chord ("E" 0 0 1 2 2 0) +(0.1 0.2 1.3 2.4 2.5 0.6){ch "E"} + +`} + +## `\hideEmptyStaves` + +```plain title="Syntax" +\hideEmptyStaves () +``` + +**Description:** Hide empty staves. + +**Example:** + +{` +\\hideEmptyStaves +\\defaultSystemsLayout 3 +\\track "Track 1" + C4 * 4 | C4 * 4 | C4 * 4 | + C4 * 4 | C4 * 4 | C4 * 4 | +\\track "Track 2" + r | r | r | + r | C4.1 | r | + +`} + +## `\hideEmptyStavesInFirstSystem` + +```plain title="Syntax" +\hideEmptyStavesInFirstSystem () +``` + +**Description:** Hide empty staves in first system. + +**Example:** + +{` +\\hideEmptyStaves +\\hideEmptyStavesInFirstSystem +\\defaultSystemsLayout 3 +\\track "Track 1" + C4 * 4 | C4 * 4 | C4 * 4 | + r | r | r | +\\track "Track 2" + r | r | r | + r | C4.1 | r | + +`} + +## `\showSingleStaffBrackets` + +```plain title="Syntax" +\showSingleStaffBrackets () +``` + +**Description:** Show brackets and braces on single staves. + +**Example:** + +{` +\\hideEmptyStaves +\\hideEmptyStavesInFirstSystem +\\showSingleStaffBrackets +\\defaultSystemsLayout 3 +\\track "Track 1" + \\staff { score } + C4 * 4 | C4 * 4 | C4 * 4 | + C4 * 4 | C4 * 4 | C4 * 4 | + \\staff { score } + r | r | r | + r | C4.1 | r | + +`} + +## `\defaultBarNumberDisplay` + +```plain title="Syntax" +\defaultBarNumberDisplay mode +``` + +**Description:** Sets the display mode for bar numbers on all bars. + +**Parameters:** + +| Name | Description | Type | Required | +|------|-------------|------|----------| +| `mode` | The mode to use | `allBars\|firstOfSystem\|hide` | yes | + +**Parameter Values:** + +Following parameters have value limitations + +| Name | Values | +|------|--------| +| `mode` | | + +**Example:** + +{` +\\defaultBarNumberDisplay allBars +\\title "All Bars" + \\track { defaultsystemslayout 3 } + C4.1 | C4.1 | C4.1 | + C4.1 | C4.1 | C4.1 + +`} +{` +\\defaultBarNumberDisplay firstOfSystem +\\title "First of System" + \\track { defaultsystemslayout 3 } + C4.1 | C4.1 | C4.1 | + C4.1 | C4.1 | C4.1 + +`} +{` +\\defaultBarNumberDisplay hide +\\title "Hide" + \\track { defaultsystemslayout 3 } + C4.1 | C4.1 | C4.1 | + C4.1 | C4.1 | C4.1 + +`} + diff --git a/docs/getting-started/installation-vite.mdx b/docs/getting-started/installation-vite.mdx index 88ff0ad..a77a467 100644 --- a/docs/getting-started/installation-vite.mdx +++ b/docs/getting-started/installation-vite.mdx @@ -12,7 +12,7 @@ import { SinceBadge } from '@site/src/components/SinceBadge'; **TL;DR:** AlphaTab comes with a Vite plugin which should be added to your Vite config to guarantee compatibility. ```js import { defineConfig } from "vite"; -import { alphaTab } from "@coderline/alphatab/vite"; +import { alphaTab } from "@coderline/alphatab-vite"; export default defineConfig({ plugins: [alphaTab()] @@ -49,9 +49,9 @@ Unless there is something special to your project setup, adding the plugin to th ```js // CommonJS -const alphaTab = require('@coderline/alphatab/vite'); +const alphaTab = require('@coderline/alphatab-vite'); // JavaScript modules -import { alphaTab } from '@coderline/alphatab/vite'; +import { alphaTab } from '@coderline/alphatab-vite'; // Add the plugin to your config export default defineConfig({ diff --git a/docs/getting-started/installation-webpack.mdx b/docs/getting-started/installation-webpack.mdx index cf3bc3f..985f8fa 100644 --- a/docs/getting-started/installation-webpack.mdx +++ b/docs/getting-started/installation-webpack.mdx @@ -11,7 +11,7 @@ import { SinceBadge } from '@site/src/components/SinceBadge'; :::info **TL;DR:** AlphaTab comes with a WebPack 5 plugin which should be added to your WebPack config to guarantee compatibility. ```js -import { AlphaTabWebPackPlugin } from '@coderline/alphatab/webpack'; +import { AlphaTabWebPackPlugin } from '@coderline/alphatab-webpack'; const webpackConfig = { plugins: [ @@ -53,9 +53,9 @@ Unless there is something special to your project setup, adding the plugin to th ```js // CommonJS -const AlphaTabWebPackPlugin = require('@coderline/alphatab/webpack'); +const AlphaTabWebPackPlugin = require('@coderline/alphatab-webpack'); // JavaScript modules -import { AlphaTabWebPackPlugin } from '@coderline/alphatab/webpack'; +import { AlphaTabWebPackPlugin } from '@coderline/alphatab-webpack'; // Add the plugin to your config const config = { @@ -193,7 +193,7 @@ In our [Angular sample](https://github.com/CoderLine/alphaTabSamplesWeb/tree/mai ``` 4. Add a `custom-webpack.config.js` and add the alphaTab Plugin ```js -const { AlphaTabWebPackPlugin } = require('@coderline/alphatab/webpack'); +const { AlphaTabWebPackPlugin } = require('@coderline/alphatab-webpack'); module.exports = { plugins: [ diff --git a/docs/guides/audio-export.mdx b/docs/guides/audio-export.mdx index fb654ed..cc1a422 100644 --- a/docs/guides/audio-export.mdx +++ b/docs/guides/audio-export.mdx @@ -34,8 +34,8 @@ The audio exporter follows an asynchronous pull pattern: To export the audio you follow tree main steps: 1. You start a new exporter with [`await api.exportAudio(...)`](/docs/reference/api/exportaudio.mdx). -2. You call [`exporter.render()`](/docs/reference/types/synth/iaudioexporter/render.mdx) to produce a chunk of audio which you can then process further. (repeated until end is reached). -3. You cleanup the exporter via [`exporter.destroy()`](/docs/reference/types/synth/iaudioexporter/destroy.mdx). The exporter also implements `Disposable` (`IDisposable` for C#, `AutoCloseable` for `Kotlin`) which allows easy cleanup via language features if supported. +2. You call [`exporter.render()`](/docs/reference/types/synth/iaudioexporter#render) to produce a chunk of audio which you can then process further. (repeated until end is reached). +3. You cleanup the exporter via [`exporter.destroy()`](/docs/reference/types/synth/iaudioexporter#destroy). The exporter also implements `Disposable` (`IDisposable` for C#, `AutoCloseable` for `Kotlin`) which allows easy cleanup via language features if supported. > [!WARNING] > The raw audio samples for a whole song can consume quite a huge amount of memory: A calculation example: @@ -52,14 +52,14 @@ To export the audio you follow tree main steps: The [`AudioExportOptions`](/docs/reference/types/synth/audioexportoptions/index.mdx) allow customizing various aspects of the audio exported: -* [`soundFonts`](/docs/reference/types/synth/audioexportoptions/soundfonts.mdx) can be used to customize the soundfonts used during export. -* [`sampleRate`](/docs/reference/types/synth/audioexportoptions/samplerate.mdx) can be used to customize the sample rate of the exported audio. -* [`useSyncPoints`](/docs/reference/types/synth/audioexportoptions/usesyncpoints.mdx) controls whether the sync points of the currently loaded song are appled during audio generation. -* [`masterVolume`](/docs/reference/types/synth/audioexportoptions/mastervolume.mdx) controls the master volume of the generated audio. -* [`metronomeVolume`](/docs/reference/types/synth/audioexportoptions/metronomevolume.mdx) controls the volume of the metronome ticks. (keep in mind that the use of `useSyncPoints` changes the audio duration, the metronome is aligned with the music notes, not with the synthesized audio) -* [`playbackRange`](/docs/reference/types/synth/audioexportoptions/playbackrange.mdx) controls the audio range which is exported. -* [`trackVolume`](/docs/reference/types/synth/audioexportoptions/trackvolume.mdx) controls the volume of every track (percentage-wise to the already configured absolute volume) -* [`trackTranspositionPitches`](/docs/reference/types/synth/audioexportoptions/tracktranspositionpitches.mdx) controls an additional transposition pitch for the tracks. +* [`soundFonts`](/docs/reference/types/synth/audioexportoptions#soundfonts) can be used to customize the soundfonts used during export. +* [`sampleRate`](/docs/reference/types/synth/audioexportoptions#samplerate) can be used to customize the sample rate of the exported audio. +* [`useSyncPoints`](/docs/reference/types/synth/audioexportoptions#usesyncpoints) controls whether the sync points of the currently loaded song are appled during audio generation. +* [`masterVolume`](/docs/reference/types/synth/audioexportoptions#mastervolume) controls the master volume of the generated audio. +* [`metronomeVolume`](/docs/reference/types/synth/audioexportoptions#metronomevolume) controls the volume of the metronome ticks. (keep in mind that the use of `useSyncPoints` changes the audio duration, the metronome is aligned with the music notes, not with the synthesized audio) +* [`playbackRange`](/docs/reference/types/synth/audioexportoptions#playbackrange) controls the audio range which is exported. +* [`trackVolume`](/docs/reference/types/synth/audioexportoptions#trackvolume) controls the volume of every track (percentage-wise to the already configured absolute volume) +* [`trackTranspositionPitches`](/docs/reference/types/synth/audioexportoptions#tracktranspositionpitches) controls an additional transposition pitch for the tracks. ## Example diff --git a/docs/guides/formatting-templates.mdx b/docs/guides/formatting-templates.mdx index b1f3849..b536805 100644 --- a/docs/guides/formatting-templates.mdx +++ b/docs/guides/formatting-templates.mdx @@ -31,9 +31,9 @@ import {FormattingTemplateSample} from '@site/src/components/FormattingTemplateS The most important parts to know: -* The [`style`](/docs/reference/types/model/score/style) on [`alphaTab.model.Score`](/docs/reference/types/model/score) is used to adjust the style of the visual elements. -* The [`headerAndFooter`](/docs/reference/types/model/scorestyle/headerandfooter) on [`alphaTab.model.ScoreStyle`](/docs/reference/types/model/scorestyle/) is used to adjust the text, visibility and alignment of the header and footer elements. -* The [`colors`](/docs/reference/types/model/elementstyle/colors) on `alphaTab.model.ScoreStyle` is used to adjust the color of the header and footer elements (and others). +* The [`style`](/docs/reference/types/model/score#style) on [`alphaTab.model.Score`](/docs/reference/types/model/score) is used to adjust the style of the visual elements. +* The [`headerAndFooter`](/docs/reference/types/model/scorestyle#headerandfooter) on [`alphaTab.model.ScoreStyle`](/docs/reference/types/model/scorestyle/) is used to adjust the text, visibility and alignment of the header and footer elements. +* The [`colors`](/docs/reference/types/model/elementstyle#colors) on `alphaTab.model.ScoreStyle` is used to adjust the color of the header and footer elements (and others). * The [`alphaTab.model.ScoreSubElement`](/docs/reference/types/model/scoresubelement) defines the possible list of elements to be styled (not all are song info related) The `template` is a string which can have following placeholders which are then replaced with the respective info of the song: diff --git a/docs/reference/_apiTable.mdx b/docs/reference/_apiTable.mdx index 9dcd26d..6afa5f0 100644 --- a/docs/reference/_apiTable.mdx +++ b/docs/reference/_apiTable.mdx @@ -191,6 +191,16 @@ import { Signature } from "@site/src/components/Signature"; This event is fired when the playback range changed. + + + + + + + + This event is fired the shown highlights for the selected playback range changes. + + @@ -343,6 +353,16 @@ import { Signature } from "@site/src/components/Signature"; Methods - Player + + + + + + + + Applies the playback range from the currently highlighted range. + + @@ -383,6 +403,16 @@ import { Signature } from "@site/src/components/Signature"; Changes the volume of the given tracks. + + + + + + + + Clears the highlight markers marking the currently selected playback range. + + @@ -410,7 +440,17 @@ import { Signature } from "@site/src/components/Signature"; - The currently configured output device if changed via . + The currently configured output device if changed via setOutputDevice . + + + + + + + + + + Places the highlight markers at the specified start and end-beat range. @@ -584,6 +624,16 @@ import { Signature } from "@site/src/components/Signature"; The UI container that holds the whole alphaTab control. + + + + + + + + An indicator by how many midi-ticks the song contents are shifted. + + @@ -655,6 +705,16 @@ import { Signature } from "@site/src/components/Signature"; The volume of the count-in metronome ticks. + + + + + + + + A custom scroll handler which will be used to handle scrolling operations during playback. + + diff --git a/docs/reference/_settingsTable.mdx b/docs/reference/_settingsTable.mdx index 7f93c06..71b7cd7 100644 --- a/docs/reference/_settingsTable.mdx +++ b/docs/reference/_settingsTable.mdx @@ -37,7 +37,7 @@ import { Signature } from "@site/src/components/Signature"; - Whether in the also the position and area of each individual note is provided. + Whether in the BoundsLookup also the position and area of each individual note is provided. @@ -192,6 +192,16 @@ import { Signature } from "@site/src/components/Signature"; The top padding applied to effect annotation staffs. + + + + + + + + The top padding applied to the first main notation staff (standard, tabs, numbered, slash). + + @@ -222,6 +232,16 @@ import { Signature } from "@site/src/components/Signature"; Whether to justify also the last system in page layouts. + + + + + + + + The bottom padding applied to last main notation staff (standard, tabs, numbered, slash). + + @@ -242,6 +262,16 @@ import { Signature } from "@site/src/components/Signature"; The layouting mode used to arrange the the notation. + + + + + + + + The additional padding to apply between multiple lyric lines. + + @@ -259,7 +289,7 @@ import { Signature } from "@site/src/components/Signature"; - The bottom padding applied to main notation staves (standard, tabs, numbered, slash). + The top padding applied to main notation staves (standard, tabs, numbered, slash). @@ -381,6 +411,16 @@ import { Signature } from "@site/src/components/Signature"; The mode used to arrange staves and systems. + + + + + + + + + The additional padding to apply between the staves of two separate tracks. + Exporter diff --git a/docs/reference/api/activebeatschanged.mdx b/docs/reference/api/activebeatschanged.mdx index 6fd5ba4..18dcf0f 100644 --- a/docs/reference/api/activebeatschanged.mdx +++ b/docs/reference/api/activebeatschanged.mdx @@ -9,9 +9,7 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when the currently active beats across all tracks change. Unlike the event this event contains the beats of all tracks and voices independent of them being rendered. +This event is fired when the currently active beats across all tracks change. Unlike the playedBeatChanged event this event contains the beats of all tracks and voices independent of them being rendered. "],["token",";"]]} @@ -31,28 +29,28 @@ This event is fired when the currently active beats across all tracks change. Un ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.activeBeatsChanged.on(args => { - updateHighlights(args.activeBeats); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.activeBeatsChanged.on(args => { + updateHighlights(args.activeBeats); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.ActiveBeatsChanged.On(args => -{ - UpdateHighlights(args.ActiveBeats); -}); +```cs +var api = new AlphaTabApi(...); +api.ActiveBeatsChanged.On(args => +{ + UpdateHighlights(args.ActiveBeats); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.activeBeatsChanged.on { args -> - updateHighlights(args.activeBeats) -} +```kotlin +val api = AlphaTabApi(...) +api.activeBeatsChanged.on { args -> + updateHighlights(args.activeBeats) +} ``` diff --git a/docs/reference/api/actualplayermode.mdx b/docs/reference/api/actualplayermode.mdx index 14ec5e6..9a2c514 100644 --- a/docs/reference/api/actualplayermode.mdx +++ b/docs/reference/api/actualplayermode.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The actual player mode which is currently active. Allows determining whether a backing track or the synthesizer is active in case automatic detection is enabled. +Applies the playback range from the currently highlighted range. This method can be used when building custom selection systems (e.g. having draggable handles). + + + + +## Examples + + + +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +const startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]; +const endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0]; +api.highlightPlaybackRange(startBeat, endBeat); +api.applyPlaybackRangeFromHighlight(); +``` + + +```cs +var api = new AlphaTabApi(...); +api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5); +api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5); +var startBeat = api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0]; +var endBeat = api.Score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0]; +api.HighlightPlaybackRange(startBeat, endBeat); +api.ApplyPlaybackRangeFromHighlight(); +``` + + +```kotlin +val api = AlphaTabApi(...) +val startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0] +val endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0] +api.highlightPlaybackRange(startBeat, endBeat) +api.applyPlaybackRangeFromHighlight() +``` + + diff --git a/docs/reference/api/beatmousedown.mdx b/docs/reference/api/beatmousedown.mdx index 1dcd930..549fe94 100644 --- a/docs/reference/api/beatmousedown.mdx +++ b/docs/reference/api/beatmousedown.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired whenever a the user presses the mouse button on a beat. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.beatMouseDown.on((beat) => { - startSelectionOnBeat(beat); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.beatMouseDown.on((beat) => { + startSelectionOnBeat(beat); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.BeatMouseDown.On(beat => -{ - StartSelectionOnBeat(args); -}); +```cs +var api = new AlphaTabApi(...); +api.BeatMouseDown.On(beat => +{ + StartSelectionOnBeat(args); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.beatMouseDown.on { beat -> - startSelectionOnBeat(args) -} +```kotlin +val api = AlphaTabApi(...) +api.beatMouseDown.on { beat -> + startSelectionOnBeat(args) +} ``` diff --git a/docs/reference/api/beatmousemove.mdx b/docs/reference/api/beatmousemove.mdx index 7697ce1..fe25624 100644 --- a/docs/reference/api/beatmousemove.mdx +++ b/docs/reference/api/beatmousemove.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired whenever the user moves the mouse over a beat after the user already pressed the button on a beat. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.beatMouseMove.on((beat) => { - expandSelectionToBeat(beat); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.beatMouseMove.on((beat) => { + expandSelectionToBeat(beat); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.BeatMouseMove.On(beat => -{ - ExpandSelectionToBeat(beat); -}); +```cs +var api = new AlphaTabApi(...); +api.BeatMouseMove.On(beat => +{ + ExpandSelectionToBeat(beat); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.beatMouseMove.on { beat -> - expandSelectionToBeat(beat) -} +```kotlin +val api = AlphaTabApi(...) +api.beatMouseMove.on { beat -> + expandSelectionToBeat(beat) +} ``` diff --git a/docs/reference/api/beatmouseup.mdx b/docs/reference/api/beatmouseup.mdx index 6ab3682..bb84f42 100644 --- a/docs/reference/api/beatmouseup.mdx +++ b/docs/reference/api/beatmouseup.mdx @@ -9,9 +9,7 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired whenever the user releases the mouse after a mouse press on a beat. This event is fired regardless of whether the mouse was released on a beat. +This event is fired whenever the user releases the mouse after a mouse press on a beat. This event is fired regardless of whether the mouse was released on a beat. The parameter is null if the mouse was released somewhere beside the beat. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.beatMouseUp.on((beat) => { - hideSelection(beat); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.beatMouseUp.on((beat) => { + hideSelection(beat); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.BeatMouseUp.On(beat => -{ - HideSelection(beat); -}); +```cs +var api = new AlphaTabApi(...); +api.BeatMouseUp.On(beat => +{ + HideSelection(beat); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.beatMouseUp.on { beat -> - hideSelection(beat) -} +```kotlin +val api = AlphaTabApi(...) +api.beatMouseUp.on { beat -> + hideSelection(beat) +} ``` diff --git a/docs/reference/api/boundslookup.mdx b/docs/reference/api/boundslookup.mdx index 33d664d..f6fa431 100644 --- a/docs/reference/api/boundslookup.mdx +++ b/docs/reference/api/boundslookup.mdx @@ -10,31 +10,29 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The tick cache allowing lookup of midi ticks to beats. In older versions of alphaTab you can access the `boundsLookup` via on . - -After the rendering completed alphaTab exposes via this lookup the location of the individual -notation elements. The lookup provides fast access to the bars and beats at a given location. -If the option was activated also the location of the individual notes can be obtained. - -The property contains a `BoundsLookup` instance which follows a hierarchical structure that represents -the tree of rendered elements. - -The hierarchy is: `staffSystems > bars(1) > bars(2) > beats > notes` - -* `staffSystems` - Represent the bounds of the individual systems ("rows") where staves are contained. -* `bars(1)` - Represent the bounds of all bars for a particular master bar across all tracks. -* `bars(2)` - Represent the bounds of an individual bar of a track. The bounds on y-axis span the region of the staff and notes might exceed this bounds. -* `beats` - Represent the bounds of the individual beats within a track. The bounds on y-axis are equal to the bar bounds. -* `notes` - Represent the bounds of the individual note heads/numbers within a track. - -Each bounds hierarchy have a `visualBounds` and `realBounds`. - -* `visualBounds` - Represent the area covering all visually visible elements -* `realBounds` - Represents the actual bounds of the elements in this beat including whitespace areas. -* `noteHeadBounds` (only on `notes` level) - Represents the area of the note heads or number based on the staff - +The tick cache allowing lookup of midi ticks to beats. In older versions of alphaTab you can access the `boundsLookup` via boundsLookup on renderer . + +After the rendering completed alphaTab exposes via this lookup the location of the individual +notation elements. The lookup provides fast access to the bars and beats at a given location. +If the CoreSettings.includeNoteBounds option was activated also the location of the individual notes can be obtained. + +The property contains a `BoundsLookup` instance which follows a hierarchical structure that represents +the tree of rendered elements. + +The hierarchy is: `staffSystems > bars(1) > bars(2) > beats > notes` + +* `staffSystems` - Represent the bounds of the individual systems ("rows") where staves are contained. +* `bars(1)` - Represent the bounds of all bars for a particular master bar across all tracks. +* `bars(2)` - Represent the bounds of an individual bar of a track. The bounds on y-axis span the region of the staff and notes might exceed this bounds. +* `beats` - Represent the bounds of the individual beats within a track. The bounds on y-axis are equal to the bar bounds. +* `notes` - Represent the bounds of the individual note heads/numbers within a track. + +Each bounds hierarchy have a `visualBounds` and `realBounds`. + +* `visualBounds` - Represent the area covering all visually visible elements +* `realBounds` - Represents the actual bounds of the elements in this beat including whitespace areas. +* `noteHeadBounds` (only on `notes` level) - Represents the area of the note heads or number based on the staff + You can check out the individual sizes and regions. - -### Description The UI container that will hold all rendered results. - -### Description -Changes the given tracks to be muted or not. This will result in a muting of the primary and secondary midi channel that the track uses +Changes the given tracks to be muted or not. This will result in a muting of the primary and secondary midi channel that the track uses for playback. If the track shares the channels with another track, all tracks will be muted as during playback they cannot be distinguished. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.changeTrackMute([api.score.tracks[0], api.score.tracks[1]], true); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.changeTrackMute([api.score.tracks[0], api.score.tracks[1]], true); ``` -```cs -var api = new AlphaTabApi(...); -api.ChangeTrackMute(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, true); +```cs +var api = new AlphaTabApi(...); +api.ChangeTrackMute(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, true); ``` -```kotlin -val api = AlphaTabApi(...) -api.changeTrackMute(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), true); +```kotlin +val api = AlphaTabApi(...) +api.changeTrackMute(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), true); ``` diff --git a/docs/reference/api/changetracksolo.mdx b/docs/reference/api/changetracksolo.mdx index f025c6c..104d36c 100644 --- a/docs/reference/api/changetracksolo.mdx +++ b/docs/reference/api/changetracksolo.mdx @@ -9,10 +9,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Changes the given tracks to be played solo or not. If any track is set to solo, all other tracks are muted, unless they are also flagged as solo. -This will result in a solo playback of the primary and secondary midi channel that the track uses for playback. +Changes the given tracks to be played solo or not. If any track is set to solo, all other tracks are muted, unless they are also flagged as solo. +This will result in a solo playback of the primary and secondary midi channel that the track uses for playback. If the track shares the channels with another track, all related tracks will be played as they cannot be distinguished. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.changeTrackSolo([api.score.tracks[0], api.score.tracks[1]], true); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.changeTrackSolo([api.score.tracks[0], api.score.tracks[1]], true); ``` -```cs -var api = new AlphaTabApi(...); -api.ChangeTrackSolo(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, true); +```cs +var api = new AlphaTabApi(...); +api.ChangeTrackSolo(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, true); ``` -```kotlin -val api = AlphaTabApi(...) -api.changeTrackSolo(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), true); +```kotlin +val api = AlphaTabApi(...) +api.changeTrackSolo(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), true); ``` diff --git a/docs/reference/api/changetracktranspositionpitch.mdx b/docs/reference/api/changetracktranspositionpitch.mdx index 5de5004..6e12461 100644 --- a/docs/reference/api/changetracktranspositionpitch.mdx +++ b/docs/reference/api/changetracktranspositionpitch.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Changes the pitch transpose applied to the given tracks. These pitches are additional to the ones applied to the song via the settings and data model and allows a more live-update via a UI. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.changeTrackTranspositionPitch([api.score.tracks[0], api.score.tracks[1]], 3); -api.changeTrackTranspositionPitch([api.score.tracks[2]], 2); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.changeTrackTranspositionPitch([api.score.tracks[0], api.score.tracks[1]], 3); +api.changeTrackTranspositionPitch([api.score.tracks[2]], 2); ``` -```cs -var api = new AlphaTabApi(...); -api.ChangeTrackTranspositionPitch(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 3); -api.ChangeTrackTranspositionPitch(new Track[] { api.Score.Tracks[2] }, 3); +```cs +var api = new AlphaTabApi(...); +api.ChangeTrackTranspositionPitch(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 3); +api.ChangeTrackTranspositionPitch(new Track[] { api.Score.Tracks[2] }, 3); ``` -```kotlin -val api = AlphaTabApi(...); -api.changeTrackTranspositionPitch(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), 3); -api.changeTrackTranspositionPitch(alphaTab.collections.List(api.score.tracks[2]), 2); +```kotlin +val api = AlphaTabApi(...); +api.changeTrackTranspositionPitch(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), 3); +api.changeTrackTranspositionPitch(alphaTab.collections.List(api.score.tracks[2]), 2); ``` diff --git a/docs/reference/api/changetrackvolume.mdx b/docs/reference/api/changetrackvolume.mdx index 626506f..e9a56cf 100644 --- a/docs/reference/api/changetrackvolume.mdx +++ b/docs/reference/api/changetrackvolume.mdx @@ -9,9 +9,7 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Changes the volume of the given tracks. This will result in a volume change of the primary and secondary midi channel that the track uses for playback. +Changes the volume of the given tracks. This will result in a volume change of the primary and secondary midi channel that the track uses for playback. If the track shares the channels with another track, all related tracks will be changed as they cannot be distinguished. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.changeTrackVolume([api.score.tracks[0], api.score.tracks[1]], 1.5); -api.changeTrackVolume([api.score.tracks[2]], 0.5); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.changeTrackVolume([api.score.tracks[0], api.score.tracks[1]], 1.5); +api.changeTrackVolume([api.score.tracks[2]], 0.5); ``` -```cs -var api = new AlphaTabApi(...); -api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5); -api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5); +```cs +var api = new AlphaTabApi(...); +api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5); +api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5); ``` -```kotlin -val api = AlphaTabApi(...); -api.changeTrackVolume(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), 1.5); -api.changeTrackVolume(alphaTab.collections.List(api.score.tracks[2]), 0.5); +```kotlin +val api = AlphaTabApi(...); +api.changeTrackVolume(alphaTab.collections.List(api.score.tracks[0], api.score.tracks[1]), 1.5); +api.changeTrackVolume(alphaTab.collections.List(api.score.tracks[2]), 0.5); ``` diff --git a/docs/reference/api/clearplaybackrangehighlight.mdx b/docs/reference/api/clearplaybackrangehighlight.mdx new file mode 100644 index 0000000..b2a7e4a --- /dev/null +++ b/docs/reference/api/clearplaybackrangehighlight.mdx @@ -0,0 +1,50 @@ +--- +title: clearPlaybackRangeHighlight +sidebar_custom_props: + kind: method + category: Methods - Player + since: 1.8.0 +--- + +import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' + + +Clears the highlight markers marking the currently selected playback range. Unlike actually setting playbackRange this method only clears the selection markers without actually +changing the playback range. This method can be used when building custom selection systems (e.g. having draggable handles). + + + + +## Examples + + + +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.clearPlaybackRangeHighlight(); +``` + + +```cs +var api = new AlphaTabApi(...); +api.clearPlaybackRangeHighlight(); +``` + + +```kotlin +val api = AlphaTabApi(...) +api.clearPlaybackRangeHighlight() +``` + + diff --git a/docs/reference/api/container.mdx b/docs/reference/api/container.mdx index f98ec54..0452826 100644 --- a/docs/reference/api/container.mdx +++ b/docs/reference/api/container.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The UI container that holds the whole alphaTab control. Gets the UI container that represents the element on which alphaTab was initialized. Note that this is not the raw instance, but a UI framework specific wrapper for alphaTab. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -const container = api.container; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +const container = api.container; ``` -```cs -var api = new AlphaTabApi(...); -var container = api.Container; +```cs +var api = new AlphaTabApi(...); +var container = api.Container; ``` -```kotlin -val api = AlphaTabApi(...) -val container = api.container; +```kotlin +val api = AlphaTabApi(...) +val container = api.container; ``` diff --git a/docs/reference/api/countinvolume.mdx b/docs/reference/api/countinvolume.mdx index 2e72514..fad9b54 100644 --- a/docs/reference/api/countinvolume.mdx +++ b/docs/reference/api/countinvolume.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The volume of the count-in metronome ticks. Gets or sets the volume of the metronome during the count-in of the song. By default the count-in is disabled but can be enabled by setting the volume different. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.countInVolume = 0.5; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.countInVolume = 0.5; ``` -```cs -var api = new AlphaTabApi(...); -api.CountInVolume = 0.5; +```cs +var api = new AlphaTabApi(...); +api.CountInVolume = 0.5; ``` -```kotlin -val api = AlphaTabApi(...) -api.countInVolume = 0.5 +```kotlin +val api = AlphaTabApi(...) +api.countInVolume = 0.5 ``` diff --git a/docs/reference/api/customscrollhandler.mdx b/docs/reference/api/customscrollhandler.mdx new file mode 100644 index 0000000..5966cdc --- /dev/null +++ b/docs/reference/api/customscrollhandler.mdx @@ -0,0 +1,59 @@ +--- +title: customScrollHandler +sidebar_custom_props: + kind: property + category: Properties - Player + since: 1.8.0 +--- + +import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, PropertyDescription } from '@site/src/reference-commons' + + + +A custom scroll handler which will be used to handle scrolling operations during playback. + + + + +## Examples + + + +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.customScrollHandler = { + forceScrollTo(currentBeatBounds) { + const scroll = api.uiFacade.getScrollElement(); + api.uiFacade.scrollToY(scroll, currentBeatBounds.barBounds.masterBarBounds.realBounds.y, 0); + }, + onBeatCursorUpdating(startBeat, endBeat, cursorMode, relativePosition, actualBeatCursorStartX, actualBeatCursorEndX, actualBeatCursorTransitionDuration) { + const scroll = api.uiFacade.getScrollElement(); + api.uiFacade.scrollToY(scroll, startBeat.barBounds.masterBarBounds.realBounds.y, 0); + } +} +``` + + +```cs +var api = new AlphaTabApi(...); +api.CustomScrollHandler = new CustomScrollHandler(); +``` + + +```kotlin +val api = AlphaTabApi(...) +api.customScrollHandler = CustomScrollHandler(); +``` + + diff --git a/docs/reference/api/destroy.mdx b/docs/reference/api/destroy.mdx index d09f0ce..168739b 100644 --- a/docs/reference/api/destroy.mdx +++ b/docs/reference/api/destroy.mdx @@ -9,10 +9,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Destroys the alphaTab control and restores the initial state of the UI. This function destroys the alphaTab control and tries to restore the initial state of the UI. This might be useful if -our website is quite dynamic and you need to uninitialize alphaTab from an element again. After destroying alphaTab +Destroys the alphaTab control and restores the initial state of the UI. This function destroys the alphaTab control and tries to restore the initial state of the UI. This might be useful if +our website is quite dynamic and you need to uninitialize alphaTab from an element again. After destroying alphaTab it cannot be used anymore. Any further usage leads to unexpected behavior. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.destroy(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.destroy(); ``` -```cs -var api = new AlphaTabApi(...); -api.Destroy(); +```cs +var api = new AlphaTabApi(...); +api.Destroy(); ``` -```kotlin -val api = AlphaTabApi(...) -api.destroy() +```kotlin +val api = AlphaTabApi(...) +api.destroy() ``` diff --git a/docs/reference/api/downloadmidi.mdx b/docs/reference/api/downloadmidi.mdx index d95332d..554e96a 100644 --- a/docs/reference/api/downloadmidi.mdx +++ b/docs/reference/api/downloadmidi.mdx @@ -10,10 +10,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Generates an SMF1.0 file and downloads it Generates a SMF1.0 compliant MIDI file of the currently loaded song and starts the download of it. -Please be aware that SMF1.0 does not support bends per note which might result in wrong bend effects +Generates an SMF1.0 file and downloads it Generates a SMF1.0 compliant MIDI file of the currently loaded song and starts the download of it. +Please be aware that SMF1.0 does not support bends per note which might result in wrong bend effects in case multiple bends are applied on the same beat (e.g. two notes bending or vibrato + bends). - -### Description The total length of the song in midi ticks. - -### Description The total length of the song in milliseconds. - -### Description -Loads and lists the available output devices which can be used by the player. Will request permissions if needed. - -The values provided, can be passed into to change dynamically the output device on which -the sound is played. - +Loads and lists the available output devices which can be used by the player. Will request permissions if needed. + +The values provided, can be passed into setOutputDevice to change dynamically the output device on which +the sound is played. + In the web version this functionality relies on experimental APIs and might not yet be available in all browsers. https://caniuse.com/mdn-api_audiocontext_sinkid -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -const devices = await api.enumerateOutputDevices(); - -buildDeviceSelector(devices, async selectedDevice => { - await api.setOutputDevice(selectedDevice); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +const devices = await api.enumerateOutputDevices(); + +buildDeviceSelector(devices, async selectedDevice => { + await api.setOutputDevice(selectedDevice); +}); ``` -```cs -var api = new AlphaTabApi(...); -var devices = await api.EnumerateOutputDevices(); - -BuildDeviceSelector(devices, async selectedDevice => { - await api.SetOutputDevice(selectedDevice); -}); +```cs +var api = new AlphaTabApi(...); +var devices = await api.EnumerateOutputDevices(); + +BuildDeviceSelector(devices, async selectedDevice => { + await api.SetOutputDevice(selectedDevice); +}); ``` -```kotlin -fun init() = kotlinx.coroutines.runBlocking { - val api = AlphaTabApi(...) - val devices = api.enumerateOutputDevices().await() - - buildDeviceSelector(devices, fun (selectedDevice) { - suspend { - await api.setOutputDevice(selectedDevice) - } - }); -} +```kotlin +fun init() = kotlinx.coroutines.runBlocking { + val api = AlphaTabApi(...) + val devices = api.enumerateOutputDevices().await() + + buildDeviceSelector(devices, fun (selectedDevice) { + suspend { + await api.setOutputDevice(selectedDevice) + } + }); +} ``` diff --git a/docs/reference/api/error.mdx b/docs/reference/api/error.mdx index 469a7f3..64663e7 100644 --- a/docs/reference/api/error.mdx +++ b/docs/reference/api/error.mdx @@ -9,10 +9,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when an error within alphatab occurred. This event is fired when an error within alphatab occurred. Use this event as global error handler to show errors -to end-users. Due to the asynchronous nature of alphaTab, no call to the API will directly throw an error if it fails. +This event is fired when an error within alphatab occurred. This event is fired when an error within alphatab occurred. Use this event as global error handler to show errors +to end-users. Due to the asynchronous nature of alphaTab, no call to the API will directly throw an error if it fails. Instead a signal to this error handlers will be sent. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.error.on((error) { - displayError(error); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.error.on((error) { + displayError(error); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.Error.On((error) => -{ - DisplayError(error); -}); +```cs +var api = new AlphaTabApi(...); +api.Error.On((error) => +{ + DisplayError(error); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.error.on { error -> - displayError(error) -} +```kotlin +val api = AlphaTabApi(...) +api.error.on { error -> + displayError(error) +} ``` diff --git a/docs/reference/api/exportaudio.mdx b/docs/reference/api/exportaudio.mdx index 4eb50a8..23baf27 100644 --- a/docs/reference/api/exportaudio.mdx +++ b/docs/reference/api/exportaudio.mdx @@ -9,11 +9,9 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Starts the audio export for the currently loaded song. This will not export or use any backing track media but will always use the synthesizer to generate the output. -This method works with any PlayerMode active but changing the mode during export can lead to unexpected side effects. - +Starts the audio export for the currently loaded song. This will not export or use any backing track media but will always use the synthesizer to generate the output. +This method works with any PlayerMode active but changing the mode during export can lead to unexpected side effects. + See [Audio Export](/docs/guides/audio-export) for further guidance how to use this feature. - -### Description -The currently configured output device if changed via . Assumes has been used. +The currently configured output device if changed via setOutputDevice . Assumes setOutputDevice has been used. In the web version this functionality relies on experimental APIs and might not yet be available in all browsers. https://caniuse.com/mdn-api_audiocontext_sinkid ### Returns -The custom configured output device which was set via or `null` -if the default outputDevice is used. +The custom configured output device which was set via setOutputDevice or `null` +if the default outputDevice is used. The output device might change dynamically if devices are connected/disconnected (e.g. bluetooth headset). @@ -37,23 +35,23 @@ The output device might change dynamically if devices are connected/disconnected ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -updateOutputDeviceUI(await api.getOutputDevice()) +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +updateOutputDeviceUI(await api.getOutputDevice()) ``` -```cs -var api = new AlphaTabApi(...); -UpdateOutputDeviceUI(await api.GetOutputDevice()) +```cs +var api = new AlphaTabApi(...); +UpdateOutputDeviceUI(await api.GetOutputDevice()) ``` -```kotlin -fun init() = kotlinx.coroutines.runBlocking { - val api = AlphaTabApi(...) - updateOutputDeviceUI(api.getOutputDevice().await()) -} +```kotlin +fun init() = kotlinx.coroutines.runBlocking { + val api = AlphaTabApi(...) + updateOutputDeviceUI(api.getOutputDevice().await()) +} ``` diff --git a/docs/reference/api/highlightplaybackrange.mdx b/docs/reference/api/highlightplaybackrange.mdx new file mode 100644 index 0000000..8743277 --- /dev/null +++ b/docs/reference/api/highlightplaybackrange.mdx @@ -0,0 +1,84 @@ +--- +title: highlightPlaybackRange +sidebar_custom_props: + kind: method + category: Methods - Player + since: 1.8.0 +--- + +import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' + + +Places the highlight markers at the specified start and end-beat range. Unlike actually setting playbackRange this method only places the selection markers without actually +changing the playback range. This method can be used when building custom selection systems (e.g. having draggable handles). + + + + + + + + + + + + + + + + + + + + +
ParameterSummary
+ + + The start beat where the selection should start +
+ + + The end beat where the selection should end. +
+ +## Examples + + + +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +const startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]; +const endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0]; +api.highlightPlaybackRange(startBeat, endBeat); +``` + + +```cs +var api = new AlphaTabApi(...); +api.ChangeTrackVolume(new Track[] { api.Score.Tracks[0], api.Score.Tracks[1] }, 1.5); +api.ChangeTrackVolume(new Track[] { api.Score.Tracks[2] }, 0.5); +var startBeat = api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0]; +var endBeat = api.Score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0]; +api.HighlightPlaybackRange(startBeat, endBeat); +``` + + +```kotlin +val api = AlphaTabApi(...) +val startBeat = api.score.tracks[0].staves[0].bars[0].voices[0].beats[0] +val endBeat = api.score.tracks[0].staves[0].bars[3].voices[0].beats[0] +api.highlightPlaybackRange(startBeat, endBeat) +``` + + diff --git a/docs/reference/api/islooping.mdx b/docs/reference/api/islooping.mdx index 807ab52..8bfed3d 100644 --- a/docs/reference/api/islooping.mdx +++ b/docs/reference/api/islooping.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description Whether the playback should automatically restart after it finished. This setting controls whether the playback should automatically restart after it finished to create a playback loop. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.isLooping = true; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.isLooping = true; ``` -```cs -var api = new AlphaTabApi(...); -api.IsLooping = true; +```cs +var api = new AlphaTabApi(...); +api.IsLooping = true; ``` -```kotlin -val api = AlphaTabApi(...) -api.isLooping = true +```kotlin +val api = AlphaTabApi(...) +api.isLooping = true ``` diff --git a/docs/reference/api/isreadyforplayback.mdx b/docs/reference/api/isreadyforplayback.mdx index a6c8fff..46fd005 100644 --- a/docs/reference/api/isreadyforplayback.mdx +++ b/docs/reference/api/isreadyforplayback.mdx @@ -10,9 +10,7 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -Whether the player is ready for starting the playback. Gets whether the synthesizer is ready for playback. The player is ready for playback when +Whether the player is ready for starting the playback. Gets whether the synthesizer is ready for playback. The player is ready for playback when all background workers are started, the audio output is initialized, a soundfont is loaded, and a song was loaded into the player as midi file. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -if(api.isReadyForPlayback)) api.play(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +if(api.isReadyForPlayback)) api.play(); ``` -```cs -var api = new AlphaTabApi(...); -if(api.IsReadyForPlayback) api.Play(); +```cs +var api = new AlphaTabApi(...); +if(api.IsReadyForPlayback) api.Play(); ``` -```kotlin -val api = AlphaTabApi(...) -if (api.isReadyForPlayback) api.play() +```kotlin +val api = AlphaTabApi(...) +if (api.isReadyForPlayback) api.play() ``` diff --git a/docs/reference/api/load.mdx b/docs/reference/api/load.mdx index 8cbb92c..377baa3 100644 --- a/docs/reference/api/load.mdx +++ b/docs/reference/api/load.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Initiates a load of the score using the given data. - The data container supported by . The supported types is depending on the platform: - - * A `alphaTab.model.Score` instance (all platforms) - * A `ArrayBuffer` or `Uint8Array` containing one of the supported file formats (all platforms, native byte array or input streams on other platforms) + The data container supported by IUiFacade . The supported types is depending on the platform: + + * A `alphaTab.model.Score` instance (all platforms) + * A `ArrayBuffer` or `Uint8Array` containing one of the supported file formats (all platforms, native byte array or input streams on other platforms) * A url from where to download the binary data of one of the supported file formats (browser only) @@ -44,7 +42,7 @@ Initiates a load of the score using the given data. - The indexes of the tracks from the song that should be rendered. If not provided, the first track of the + The indexes of the tracks from the song that should be rendered. If not provided, the first track of the song will be shown. @@ -65,23 +63,23 @@ true if the data object is supported and a load was initiated, otherwise false ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.load('/assets/MyFile.gp'); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.load('/assets/MyFile.gp'); ``` -```cs -var api = new AlphaTabApi(...); -api.Load(System.IO.File.OpenRead("MyFile.gp")); +```cs +var api = new AlphaTabApi(...); +api.Load(System.IO.File.OpenRead("MyFile.gp")); ``` -```kotlin -val api = AlphaTabApi(...) -contentResolver.openInputStream(uri).use { - api.load(it) -} +```kotlin +val api = AlphaTabApi(...) +contentResolver.openInputStream(uri).use { + api.load(it) +} ``` diff --git a/docs/reference/api/loadmidiforscore.mdx b/docs/reference/api/loadmidiforscore.mdx index c71f98b..783ca63 100644 --- a/docs/reference/api/loadmidiforscore.mdx +++ b/docs/reference/api/loadmidiforscore.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Re-creates the midi for the current score and loads it. This will result in the player to stop playback. Some setting changes require re-genration of the midi song. - -### Description Triggers a load of the soundfont from the given data. AlphaTab only supports SoundFont2 and SoundFont3 encoded soundfonts for loading. To load a soundfont the player must be enabled in advance. - The data object to decode. The supported data types is depending on the platform. - - * A `ArrayBuffer` or `Uint8Array` (all platforms, native byte array or input streams on other platforms) + The data object to decode. The supported data types is depending on the platform. + + * A `ArrayBuffer` or `Uint8Array` (all platforms, native byte array or input streams on other platforms) * A url from where to download the binary data of one of the supported file formats (browser only) @@ -63,23 +61,23 @@ Triggers a load of the soundfont from the given data. AlphaTab only supports Sou ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.loadSoundFont('/assets/MyFile.sf2'); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.loadSoundFont('/assets/MyFile.sf2'); ``` -```cs -var api = new AlphaTabApi(...); -api.LoadSoundFont(System.IO.File.OpenRead("MyFile.sf2")); +```cs +var api = new AlphaTabApi(...); +api.LoadSoundFont(System.IO.File.OpenRead("MyFile.sf2")); ``` -```kotlin -val api = AlphaTabApi(...) -contentResolver.openInputStream(uri).use { - api.loadSoundFont(it) -} +```kotlin +val api = AlphaTabApi(...) +contentResolver.openInputStream(uri).use { + api.loadSoundFont(it) +} ``` diff --git a/docs/reference/api/loadsoundfontfromurl.mdx b/docs/reference/api/loadsoundfontfromurl.mdx index f9b8712..8d6cd95 100644 --- a/docs/reference/api/loadsoundfontfromurl.mdx +++ b/docs/reference/api/loadsoundfontfromurl.mdx @@ -10,8 +10,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Triggers a load of the soundfont from the given URL. - -### Description The current master volume as percentage (0-1). Gets or sets the master volume of the overall audio being played. The volume is annotated in percentage where 1.0 would be the normal volume and 0.5 only 50%. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.masterVolume = 0.5; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.masterVolume = 0.5; ``` -```cs -var api = new AlphaTabApi(...); -api.MasterVolume = 0.5; +```cs +var api = new AlphaTabApi(...); +api.MasterVolume = 0.5; ``` -```kotlin -val api = AlphaTabApi(...) -api.masterVolume = 0.5 +```kotlin +val api = AlphaTabApi(...) +api.masterVolume = 0.5 ``` diff --git a/docs/reference/api/metronomevolume.mdx b/docs/reference/api/metronomevolume.mdx index 6c1aab8..44dfe3e 100644 --- a/docs/reference/api/metronomevolume.mdx +++ b/docs/reference/api/metronomevolume.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The metronome volume as percentage (0-1). Gets or sets the volume of the metronome. By default the metronome is disabled but can be enabled by setting the volume different. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.metronomeVolume = 0.5; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.metronomeVolume = 0.5; ``` -```cs -var api = new AlphaTabApi(...); -api.MetronomeVolume = 0.5; +```cs +var api = new AlphaTabApi(...); +api.MetronomeVolume = 0.5; ``` -```kotlin -val api = AlphaTabApi(...) -api.metronomeVolume = 0.5 +```kotlin +val api = AlphaTabApi(...) +api.metronomeVolume = 0.5 ``` diff --git a/docs/reference/api/midieventsplayed.mdx b/docs/reference/api/midieventsplayed.mdx index ecc8e69..4c62daf 100644 --- a/docs/reference/api/midieventsplayed.mdx +++ b/docs/reference/api/midieventsplayed.mdx @@ -9,14 +9,12 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when the synthesizer played certain midi events. This event is fired when the synthesizer played certain midi events. This allows reacing on various low level -audio playback elements like notes/rests played or metronome ticks. - -Refer to the [related guide](/docs/guides/handling-midi-events) to learn more about this feature. - -Also note that the provided data models changed significantly in `{@version 1.3.0}`. We try to provide backwards compatibility +This event is fired when the synthesizer played certain midi events. This event is fired when the synthesizer played certain midi events. This allows reacing on various low level +audio playback elements like notes/rests played or metronome ticks. + +Refer to the [related guide](/docs/guides/handling-midi-events) to learn more about this feature. + +Also note that the provided data models changed significantly in `{@version 1.3.0}`. We try to provide backwards compatibility until some extend but highly encourage changing to the new models in case of problems. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.midiEventsPlayedFilter = [alphaTab.midi.MidiEventType.AlphaTabMetronome]; -api.midiEventsPlayed.on(function(e) { - for(const midi of e.events) { - if(midi.isMetronome) { - console.log('Metronome tick ' + midi.tick); - } - } -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.midiEventsPlayedFilter = [alphaTab.midi.MidiEventType.AlphaTabMetronome]; +api.midiEventsPlayed.on(function(e) { + for(const midi of e.events) { + if(midi.isMetronome) { + console.log('Metronome tick ' + midi.tick); + } + } +}); ``` -```cs -var api = new AlphaTabApi(...); -api.MidiEventsPlayedFilter = new MidiEventType[] { AlphaTab.Midi.MidiEventType.AlphaTabMetronome }; -api.MidiEventsPlayed.On(e => -{ - foreach(var midi of e.events) - { - if(midi is AlphaTab.Midi.AlphaTabMetronomeEvent sysex && sysex.IsMetronome) - { - Console.WriteLine("Metronome tick " + midi.Tick); - } - } -}); +```cs +var api = new AlphaTabApi(...); +api.MidiEventsPlayedFilter = new MidiEventType[] { AlphaTab.Midi.MidiEventType.AlphaTabMetronome }; +api.MidiEventsPlayed.On(e => +{ + foreach(var midi of e.events) + { + if(midi is AlphaTab.Midi.AlphaTabMetronomeEvent sysex && sysex.IsMetronome) + { + Console.WriteLine("Metronome tick " + midi.Tick); + } + } +}); ``` -```kotlin -val api = AlphaTabApi(...); -api.midiEventsPlayedFilter = alphaTab.collections.List( alphaTab.midi.MidiEventType.AlphaTabMetronome ) -api.midiEventsPlayed.on { e -> - for (midi in e.events) { - if(midi instanceof alphaTab.midi.AlphaTabMetronomeEvent && midi.isMetronome) { - println("Metronome tick " + midi.tick); - } - } -} +```kotlin +val api = AlphaTabApi(...); +api.midiEventsPlayedFilter = alphaTab.collections.List( alphaTab.midi.MidiEventType.AlphaTabMetronome ) +api.midiEventsPlayed.on { e -> + for (midi in e.events) { + if(midi instanceof alphaTab.midi.AlphaTabMetronomeEvent && midi.isMetronome) { + println("Metronome tick " + midi.tick); + } + } +} ``` diff --git a/docs/reference/api/midieventsplayedfilter.mdx b/docs/reference/api/midieventsplayedfilter.mdx index 1db8f30..770df2a 100644 --- a/docs/reference/api/midieventsplayedfilter.mdx +++ b/docs/reference/api/midieventsplayedfilter.mdx @@ -10,12 +10,10 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The midi events which will trigger the `midiEventsPlayed` event Gets or sets the midi events which will trigger the `midiEventsPlayed` event. With this filter set you can enable -that alphaTab will signal any midi events as they are played by the synthesizer. This allows reacing on various low level -audio playback elements like notes/rests played or metronome ticks. - +The midi events which will trigger the `midiEventsPlayed` event Gets or sets the midi events which will trigger the `midiEventsPlayed` event. With this filter set you can enable +that alphaTab will signal any midi events as they are played by the synthesizer. This allows reacing on various low level +audio playback elements like notes/rests played or metronome ticks. + Refer to the [related guide](/docs/guides/handling-midi-events) to learn more about this feature. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.midiEventsPlayedFilter = [alphaTab.midi.MidiEventType.AlphaTabMetronome]; -api.midiEventsPlayed.on(function(e) { - for(const midi of e.events) { - if(midi.isMetronome) { - console.log('Metronome tick ' + midi.metronomeNumerator); - } - } -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.midiEventsPlayedFilter = [alphaTab.midi.MidiEventType.AlphaTabMetronome]; +api.midiEventsPlayed.on(function(e) { + for(const midi of e.events) { + if(midi.isMetronome) { + console.log('Metronome tick ' + midi.metronomeNumerator); + } + } +}); ``` -```cs -var api = new AlphaTabApi(...); -api.MidiEventsPlayedFilter = new MidiEventType[] { AlphaTab.Midi.MidiEventType.AlphaTabMetronome }; -api.MidiEventsPlayed.On(e => -{ - foreach(var midi of e.events) - { - if(midi is AlphaTab.Midi.AlphaTabMetronomeEvent metronome) - { - Console.WriteLine("Metronome tick " + metronome.MetronomeNumerator); - } - } -}); +```cs +var api = new AlphaTabApi(...); +api.MidiEventsPlayedFilter = new MidiEventType[] { AlphaTab.Midi.MidiEventType.AlphaTabMetronome }; +api.MidiEventsPlayed.On(e => +{ + foreach(var midi of e.events) + { + if(midi is AlphaTab.Midi.AlphaTabMetronomeEvent metronome) + { + Console.WriteLine("Metronome tick " + metronome.MetronomeNumerator); + } + } +}); ``` -```kotlin -val api = AlphaTabApi(...); -api.midiEventsPlayedFilter = alphaTab.collections.List( alphaTab.midi.MidiEventType.AlphaTabMetronome ) -api.midiEventsPlayed.on { e -> - for (midi in e.events) { - if(midi instanceof alphaTab.midi.AlphaTabMetronomeEvent && midi.isMetronome) { - println("Metronome tick " + midi.tick); - } - } -} +```kotlin +val api = AlphaTabApi(...); +api.midiEventsPlayedFilter = alphaTab.collections.List( alphaTab.midi.MidiEventType.AlphaTabMetronome ) +api.midiEventsPlayed.on { e -> + for (midi in e.events) { + if(midi instanceof alphaTab.midi.AlphaTabMetronomeEvent && midi.isMetronome) { + println("Metronome tick " + midi.tick); + } + } +} ``` diff --git a/docs/reference/api/midiload.mdx b/docs/reference/api/midiload.mdx index 65d781c..9c21bf1 100644 --- a/docs/reference/api/midiload.mdx +++ b/docs/reference/api/midiload.mdx @@ -9,15 +9,13 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when a Midi file is being loaded. This event is fired when a Midi file for the song was generated and is being loaded -by the synthesizer. This event can be used to inspect or modify the midi events -which will be played for the song. This can be used to generate other visual representations -of the song. - -> [!NOTE] -> The generated midi file will NOT contain any metronome and count-in related events. The metronome and +This event is fired when a Midi file is being loaded. This event is fired when a Midi file for the song was generated and is being loaded +by the synthesizer. This event can be used to inspect or modify the midi events +which will be played for the song. This can be used to generate other visual representations +of the song. + +> [!NOTE] +> The generated midi file will NOT contain any metronome and count-in related events. The metronome and > count-in ticks are handled within the synthesizer. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.midiLoad.on(file => { - initializePianoPractice(file); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.midiLoad.on(file => { + initializePianoPractice(file); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.MidiLoad.On(file => -{ - InitializePianoPractice(file); -}); +```cs +var api = new AlphaTabApi(...); +api.MidiLoad.On(file => +{ + InitializePianoPractice(file); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.midiLoad.on { file -> - initializePianoPractice(file) -} +```kotlin +val api = AlphaTabApi(...) +api.midiLoad.on { file -> + initializePianoPractice(file) +} ``` diff --git a/docs/reference/api/midiloaded.mdx b/docs/reference/api/midiloaded.mdx index f15eaea..db8e976 100644 --- a/docs/reference/api/midiloaded.mdx +++ b/docs/reference/api/midiloaded.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the Midi file needed for playback was loaded. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.midiLoaded.on(e => { - hideGeneratingAudioIndicator(); - updateSongDuration(e.endTime); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.midiLoaded.on(e => { + hideGeneratingAudioIndicator(); + updateSongDuration(e.endTime); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.MidiLoaded.On(e => -{ - HideGeneratingAudioIndicator(); - UpdateSongDuration(e.EndTime); -}); +```cs +var api = new AlphaTabApi(...); +api.MidiLoaded.On(e => +{ + HideGeneratingAudioIndicator(); + UpdateSongDuration(e.EndTime); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.midiLoaded.on { e -> - hideGeneratingAudioIndicator() - updateSongDuration(e.endTime) -} +```kotlin +val api = AlphaTabApi(...) +api.midiLoaded.on { e -> + hideGeneratingAudioIndicator() + updateSongDuration(e.endTime) +} ``` diff --git a/docs/reference/api/miditickshift.mdx b/docs/reference/api/miditickshift.mdx new file mode 100644 index 0000000..a4f4207 --- /dev/null +++ b/docs/reference/api/miditickshift.mdx @@ -0,0 +1,20 @@ +--- +title: midiTickShift +sidebar_custom_props: + kind: property + category: Properties - Core +--- + +import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, PropertyDescription } from '@site/src/reference-commons' + + +An indicator by how many midi-ticks the song contents are shifted. +Grace beats at start might require a shift for the first beat to start at 0. +This information can be used to translate back the player time axis to the music notation. + + + diff --git a/docs/reference/api/notemousedown.mdx b/docs/reference/api/notemousedown.mdx index 5cbbc73..a3a8442 100644 --- a/docs/reference/api/notemousedown.mdx +++ b/docs/reference/api/notemousedown.mdx @@ -9,11 +9,9 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired whenever a the user presses the mouse button on a note head/number. This event is fired whenever a the user presses the mouse button on a note. -It is only fired if was set to `true` because -only then this hit detection can be done. A click on a note is considered if the note head or the note number on tabs are clicked as documented in . +This event is fired whenever a the user presses the mouse button on a note head/number. This event is fired whenever a the user presses the mouse button on a note. +It is only fired if CoreSettings.includeNoteBounds was set to `true` because +only then this hit detection can be done. A click on a note is considered if the note head or the note number on tabs are clicked as documented in boundsLookup . "],["token",";"]]} @@ -33,28 +31,28 @@ only then this hit detection can be done. A click on a note is considered if the ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.noteMouseDown.on((note) => { - api.playNote(note); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.noteMouseDown.on((note) => { + api.playNote(note); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.NoteMouseDown.On(note => -{ - api.PlayNote(note); -}); +```cs +var api = new AlphaTabApi(...); +api.NoteMouseDown.On(note => +{ + api.PlayNote(note); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.noteMouseDown.on { note -> - api.playNote(note) -} +```kotlin +val api = AlphaTabApi(...) +api.noteMouseDown.on { note -> + api.playNote(note) +} ``` diff --git a/docs/reference/api/notemousemove.mdx b/docs/reference/api/notemousemove.mdx index fcb8216..e420418 100644 --- a/docs/reference/api/notemousemove.mdx +++ b/docs/reference/api/notemousemove.mdx @@ -9,11 +9,9 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired whenever the user moves the mouse over a note after the user already pressed the button on a note. This event is fired whenever the user moves the mouse over a note after the user already pressed the button on a note. -It is only fired if was set to `true` because -only then this hit detection can be done. A click on a note is considered if the note head or the note number on tabs are clicked as documented in +This event is fired whenever the user moves the mouse over a note after the user already pressed the button on a note. This event is fired whenever the user moves the mouse over a note after the user already pressed the button on a note. +It is only fired if CoreSettings.includeNoteBounds was set to `true` because +only then this hit detection can be done. A click on a note is considered if the note head or the note number on tabs are clicked as documented in boundsLookup "],["token",";"]]} @@ -33,28 +31,28 @@ only then this hit detection can be done. A click on a note is considered if the ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.noteMouseMove.on((note) => { - changeNote(note) -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.noteMouseMove.on((note) => { + changeNote(note) +}); ``` -```cs -var api = new AlphaTabApi(...); -api.NoteMouseMove.On(note => -{ - ChangeNote(note); -}); +```cs +var api = new AlphaTabApi(...); +api.NoteMouseMove.On(note => +{ + ChangeNote(note); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.noteMouseMove.on { note -> - changeNote(note) -} +```kotlin +val api = AlphaTabApi(...) +api.noteMouseMove.on { note -> + changeNote(note) +} ``` diff --git a/docs/reference/api/notemouseup.mdx b/docs/reference/api/notemouseup.mdx index d6da8d4..69f5f67 100644 --- a/docs/reference/api/notemouseup.mdx +++ b/docs/reference/api/notemouseup.mdx @@ -9,13 +9,11 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired whenever the user releases the mouse after a mouse press on a note. This event is fired whenever a the user presses the mouse button on a note. -This event is fired regardless of whether the mouse was released on a note. -The parameter is null if the mouse was released somewhere beside the note. -It is only fired if was set to `true` because -only then this hit detection can be done. A click on a note is considered if the note head or the note number on tabs are clicked as documented in the . +This event is fired whenever the user releases the mouse after a mouse press on a note. This event is fired whenever a the user presses the mouse button on a note. +This event is fired regardless of whether the mouse was released on a note. +The parameter is null if the mouse was released somewhere beside the note. +It is only fired if CoreSettings.includeNoteBounds was set to `true` because +only then this hit detection can be done. A click on a note is considered if the note head or the note number on tabs are clicked as documented in the boundsLookup . "],["token",";"]]} @@ -35,28 +33,28 @@ only then this hit detection can be done. A click on a note is considered if the ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.noteMouseUp.on((note) => { - api.playNote(note); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.noteMouseUp.on((note) => { + api.playNote(note); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.NoteMouseUp.On(note => -{ - api.PlayNote(note); -}); +```cs +var api = new AlphaTabApi(...); +api.NoteMouseUp.On(note => +{ + api.PlayNote(note); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.noteMouseUp.on { note -> - api.playNote(note) -} +```kotlin +val api = AlphaTabApi(...) +api.noteMouseUp.on { note -> + api.playNote(note) +} ``` diff --git a/docs/reference/api/pause.mdx b/docs/reference/api/pause.mdx index 6fa8f1d..550aa70 100644 --- a/docs/reference/api/pause.mdx +++ b/docs/reference/api/pause.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Pauses the playback of the current song. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.pause(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.pause(); ``` -```cs -var api = new AlphaTabApi(...); -api.Pause(); +```cs +var api = new AlphaTabApi(...); +api.Pause(); ``` -```kotlin -val api = AlphaTabApi(...) -api.pause(); +```kotlin +val api = AlphaTabApi(...) +api.pause(); ``` diff --git a/docs/reference/api/play.mdx b/docs/reference/api/play.mdx index ad0ac86..e85581f 100644 --- a/docs/reference/api/play.mdx +++ b/docs/reference/api/play.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Starts the playback of the current song. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.play(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.play(); ``` -```cs -var api = new AlphaTabApi(...); -api.Play(); +```cs +var api = new AlphaTabApi(...); +api.Play(); ``` -```kotlin -val api = AlphaTabApi(...) -api.play() +```kotlin +val api = AlphaTabApi(...) +api.play() ``` diff --git a/docs/reference/api/playbackrange.mdx b/docs/reference/api/playbackrange.mdx index db75fa1..83884ab 100644 --- a/docs/reference/api/playbackrange.mdx +++ b/docs/reference/api/playbackrange.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The range of the song that should be played. Gets or sets the range of the song that should be played. The range is defined in midi ticks or the whole song is played if the range is set to null -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playbackRange = { startTick: 1000, endTick: 50000 }; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playbackRange = { startTick: 1000, endTick: 50000 }; ``` -```cs -var api = new AlphaTabApi(...); -api.PlaybackRange = new PlaybackRange { StartTick = 1000, EndTick = 50000 }; +```cs +var api = new AlphaTabApi(...); +api.PlaybackRange = new PlaybackRange { StartTick = 1000, EndTick = 50000 }; ``` -```kotlin -val api = AlphaTabApi(...) -api.playbackRange = PlaybackRange.apply { - startTick = 1000 - endTick = 50000 -} +```kotlin +val api = AlphaTabApi(...) +api.playbackRange = PlaybackRange.apply { + startTick = 1000 + endTick = 50000 +} ``` diff --git a/docs/reference/api/playbackrangechanged.mdx b/docs/reference/api/playbackrangechanged.mdx index e1c04eb..50e163a 100644 --- a/docs/reference/api/playbackrangechanged.mdx +++ b/docs/reference/api/playbackrangechanged.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the playback range changed. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playbackRangeChanged.on((args) => { - if (args.playbackRange) { - highlightRangeInProgressBar(args.playbackRange.startTick, args.playbackRange.endTick); - } else { - clearHighlightInProgressBar(); - } -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playbackRangeChanged.on((args) => { + if (args.playbackRange) { + highlightRangeInProgressBar(args.playbackRange.startTick, args.playbackRange.endTick); + } else { + clearHighlightInProgressBar(); + } +}); ``` -```cs -var api = new AlphaTabApi(...); -api.PlaybackRangeChanged.On(args => -{ - if (args.PlaybackRange != null) - { - HighlightRangeInProgressBar(args.PlaybackRange.StartTick, args.PlaybackRange.EndTick); - } - else - { - ClearHighlightInProgressBar(); - } -}); +```cs +var api = new AlphaTabApi(...); +api.PlaybackRangeChanged.On(args => +{ + if (args.PlaybackRange != null) + { + HighlightRangeInProgressBar(args.PlaybackRange.StartTick, args.PlaybackRange.EndTick); + } + else + { + ClearHighlightInProgressBar(); + } +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.playbackRangeChanged.on { args -> - val playbackRange = args.playbackRange - if (playbackRange != null) { - highlightRangeInProgressBar(playbackRange.startTick, playbackRange.endTick) - } else { - clearHighlightInProgressBar() - } -} +```kotlin +val api = AlphaTabApi(...) +api.playbackRangeChanged.on { args -> + val playbackRange = args.playbackRange + if (playbackRange != null) { + highlightRangeInProgressBar(playbackRange.startTick, playbackRange.endTick) + } else { + clearHighlightInProgressBar() + } +} ``` diff --git a/docs/reference/api/playbackrangehighlightchanged.mdx b/docs/reference/api/playbackrangehighlightchanged.mdx new file mode 100644 index 0000000..b15b2e4 --- /dev/null +++ b/docs/reference/api/playbackrangehighlightchanged.mdx @@ -0,0 +1,57 @@ +--- +title: playbackRangeHighlightChanged +sidebar_custom_props: + kind: event + category: Events - Player + since: 1.8.0 +--- + +import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' + + +This event is fired the shown highlights for the selected playback range changes. This event is fired already during selection and not only when the selection is completed. +This event can be used to place additional custom selection markers (like drag handles). + +"],["token",";"]]} + csharp={[["identifier","IEventEmitterOfT","/docs/reference/types/ieventemitteroft"],["token","<"],["identifier","PlaybackHighlightChangeEventArgs","/docs/reference/types/playbackhighlightchangeeventargs"],["token",">"],["whitespace"," "],["identifier","PlaybackRangeHighlightChanged"],["whitespace"," "],["token","{"],["whitespace"," "],["keyword","get"],["token",";"],["whitespace"," "],["token","}"]]} + kotlin={[["keyword","val"],["whitespace"," "],["identifier","playbackRangeHighlightChanged"],["token",":"],["whitespace"," "],["identifier","IEventEmitterOfT","/docs/reference/types/ieventemitteroft"],["token","<"],["identifier","PlaybackHighlightChangeEventArgs","/docs/reference/types/playbackhighlightchangeeventargs"],["token",">"]]} +/> + + +## Examples + + + +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playbackRangeHighlightChanged.on(e => { + updateSelectionHandles(e); +}); +``` + + +```cs +var api = new AlphaTabApi(...); +api.PlaybackRangeHighlightChanged.On(e => +{ + UpdateSelectionHandles(e); +}); +``` + + +```kotlin +val api = AlphaTabApi(...) +api.playbackRangeHighlightChanged.on { e -> + updateSelectionHandles(e) +} +``` + + diff --git a/docs/reference/api/playbackspeed.mdx b/docs/reference/api/playbackspeed.mdx index fa41a16..b941cc3 100644 --- a/docs/reference/api/playbackspeed.mdx +++ b/docs/reference/api/playbackspeed.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The current playback speed as percentage Controls the current playback speed as percentual value. Normal speed is 1.0 (100%) and 0.5 would be 50%. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playbackSpeed = 0.5; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playbackSpeed = 0.5; ``` -```cs -var api = new AlphaTabApi(...); -api.PlaybackSpeed = 0.5; +```cs +var api = new AlphaTabApi(...); +api.PlaybackSpeed = 0.5; ``` -```kotlin -val api = AlphaTabApi(...) -api.playbackSpeed = 0.5 +```kotlin +val api = AlphaTabApi(...) +api.playbackSpeed = 0.5 ``` diff --git a/docs/reference/api/playbeat.mdx b/docs/reference/api/playbeat.mdx index d1ae8c7..1ecc881 100644 --- a/docs/reference/api/playbeat.mdx +++ b/docs/reference/api/playbeat.mdx @@ -9,11 +9,9 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Triggers the play of the given beat. This will stop the any other current ongoing playback. -This method can be used in applications when individual beats need to be played for lesson or editor style purposes. -The player will not report any change in state or playback position during the playback of the requested beat. +Triggers the play of the given beat. This will stop the any other current ongoing playback. +This method can be used in applications when individual beats need to be played for lesson or editor style purposes. +The player will not report any change in state or playback position during the playback of the requested beat. It is a playback of audio separate to the main song playback. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playBeat(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playBeat(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayBeat(api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0]); +```cs +var api = new AlphaTabApi(...); +api.PlayBeat(api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0]); ``` -```kotlin -val api = AlphaTabApi(...) -api.playBeat(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]) +```kotlin +val api = AlphaTabApi(...) +api.playBeat(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0]) ``` diff --git a/docs/reference/api/playedbeatchanged.mdx b/docs/reference/api/playedbeatchanged.mdx index 8b09eda..bda29e0 100644 --- a/docs/reference/api/playedbeatchanged.mdx +++ b/docs/reference/api/playedbeatchanged.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the played beat changed. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playedBeatChanged.on((beat) => { - updateFretboard(beat); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playedBeatChanged.on((beat) => { + updateFretboard(beat); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayedBeatChanged.On(beat => -{ - UpdateFretboard(beat); -}); +```cs +var api = new AlphaTabApi(...); +api.PlayedBeatChanged.On(beat => +{ + UpdateFretboard(beat); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.playedBeatChanged.on { beat -> - updateFretboard(beat) -} +```kotlin +val api = AlphaTabApi(...) +api.playedBeatChanged.on { beat -> + updateFretboard(beat) +} ``` diff --git a/docs/reference/api/player.mdx b/docs/reference/api/player.mdx index eb36e5d..cd8c8a6 100644 --- a/docs/reference/api/player.mdx +++ b/docs/reference/api/player.mdx @@ -10,10 +10,8 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The alphaSynth player used for playback. This is the low-level API to the Midi synthesizer used for playback. -Gets access to the underling that is used for the audio playback. +The alphaSynth player used for playback. This is the low-level API to the Midi synthesizer used for playback. +Gets access to the underling IAlphaSynth that is used for the audio playback. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -setupPlayerEvents(api.settings); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +setupPlayerEvents(api.settings); ``` -```cs -var api = new AlphaTabApi(...); -SetupPlayerEvents(api.Player); +```cs +var api = new AlphaTabApi(...); +SetupPlayerEvents(api.Player); ``` -```kotlin -val api = AlphaTabApi(...) -setupPlayerEvents(api.player) +```kotlin +val api = AlphaTabApi(...) +setupPlayerEvents(api.player) ``` diff --git a/docs/reference/api/playerfinished.mdx b/docs/reference/api/playerfinished.mdx index d1af608..2f8d3a5 100644 --- a/docs/reference/api/playerfinished.mdx +++ b/docs/reference/api/playerfinished.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the playback of the whole song finished. This event is finished regardless on whether looping is enabled or not. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playerFinished.on((args) => { - // speed trainer - api.playbackSpeed = Math.min(1.0, api.playbackSpeed + 0.1); -}); -api.isLooping = true; -api.playbackSpeed = 0.5; -api.play() +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playerFinished.on((args) => { + // speed trainer + api.playbackSpeed = Math.min(1.0, api.playbackSpeed + 0.1); +}); +api.isLooping = true; +api.playbackSpeed = 0.5; +api.play() ``` -```cs -var api = new AlphaTabApi(...); -api.PlayerFinished.On(() => -{ - // speed trainer - api.PlaybackSpeed = Math.Min(1.0, api.PlaybackSpeed + 0.1); -}); -api.IsLooping = true; -api.PlaybackSpeed = 0.5; -api.Play(); +```cs +var api = new AlphaTabApi(...); +api.PlayerFinished.On(() => +{ + // speed trainer + api.PlaybackSpeed = Math.Min(1.0, api.PlaybackSpeed + 0.1); +}); +api.IsLooping = true; +api.PlaybackSpeed = 0.5; +api.Play(); ``` -```kotlin -val api = AlphaTabApi(...) -api.playerFinished.on { - // speed trainer - api.playbackSpeed = min(1.0, api.playbackSpeed + 0.1); -} -api.isLooping = true -api.playbackSpeed = 0.5 -api.play() +```kotlin +val api = AlphaTabApi(...) +api.playerFinished.on { + // speed trainer + api.playbackSpeed = min(1.0, api.playbackSpeed + 0.1); +} +api.isLooping = true +api.playbackSpeed = 0.5 +api.play() ``` diff --git a/docs/reference/api/playerpositionchanged.mdx b/docs/reference/api/playerpositionchanged.mdx index 7d60078..8313691 100644 --- a/docs/reference/api/playerpositionchanged.mdx +++ b/docs/reference/api/playerpositionchanged.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the current playback position of the song changed. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playerPositionChanged.on((args) => { - updatePlayerPosition(args); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playerPositionChanged.on((args) => { + updatePlayerPosition(args); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayerPositionChanged.On(args => -{ - UpdatePlayerPosition(args); -}); +```cs +var api = new AlphaTabApi(...); +api.PlayerPositionChanged.On(args => +{ + UpdatePlayerPosition(args); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.playerPositionChanged.on { args -> - updatePlayerPosition(args) -} +```kotlin +val api = AlphaTabApi(...) +api.playerPositionChanged.on { args -> + updatePlayerPosition(args) +} ``` diff --git a/docs/reference/api/playerready.mdx b/docs/reference/api/playerready.mdx index a6a7f5f..cee985a 100644 --- a/docs/reference/api/playerready.mdx +++ b/docs/reference/api/playerready.mdx @@ -9,9 +9,7 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when all required data for playback is loaded and ready. This event is fired when all required data for playback is loaded and ready. The player is ready for playback when +This event is fired when all required data for playback is loaded and ready. This event is fired when all required data for playback is loaded and ready. The player is ready for playback when all background workers are started, the audio output is initialized, a soundfont is loaded, and a song was loaded into the player as midi file. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playerReady.on(() => { - enablePlayerControls(); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playerReady.on(() => { + enablePlayerControls(); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayerReady.On(() => -{ - EnablePlayerControls() -}); +```cs +var api = new AlphaTabApi(...); +api.PlayerReady.On(() => +{ + EnablePlayerControls() +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.playerReady.on { - enablePlayerControls() -} +```kotlin +val api = AlphaTabApi(...) +api.playerReady.on { + enablePlayerControls() +} ``` diff --git a/docs/reference/api/playerstate.mdx b/docs/reference/api/playerstate.mdx index ae56c24..336c411 100644 --- a/docs/reference/api/playerstate.mdx +++ b/docs/reference/api/playerstate.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The current player state. Gets the current player state, meaning whether it is paused or playing. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -if(api.playerState != alphaTab.synth.PlayerState.Playing) api.play(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +if(api.playerState != alphaTab.synth.PlayerState.Playing) api.play(); ``` -```cs -var api = new AlphaTabApi(...); -if(api.PlayerState != PlayerState.Playing) api.Play(); +```cs +var api = new AlphaTabApi(...); +if(api.PlayerState != PlayerState.Playing) api.Play(); ``` -```kotlin -val api = AlphaTabApi(...) -if (api.playerState != PlayerState.Playing) api.play() +```kotlin +val api = AlphaTabApi(...) +if (api.playerState != PlayerState.Playing) api.play() ``` diff --git a/docs/reference/api/playerstatechanged.mdx b/docs/reference/api/playerstatechanged.mdx index fcdcd46..0456ab9 100644 --- a/docs/reference/api/playerstatechanged.mdx +++ b/docs/reference/api/playerstatechanged.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the playback state changed. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playerStateChanged.on((args) => { - updatePlayerControls(args.state, args.stopped); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playerStateChanged.on((args) => { + updatePlayerControls(args.state, args.stopped); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayerStateChanged.On(args => -{ - UpdatePlayerControls(args); -}); +```cs +var api = new AlphaTabApi(...); +api.PlayerStateChanged.On(args => +{ + UpdatePlayerControls(args); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.playerStateChanged.on { args -> - updatePlayerControls(args) -} +```kotlin +val api = AlphaTabApi(...) +api.playerStateChanged.on { args -> + updatePlayerControls(args) +} ``` diff --git a/docs/reference/api/playnote.mdx b/docs/reference/api/playnote.mdx index ae3f643..bfbe684 100644 --- a/docs/reference/api/playnote.mdx +++ b/docs/reference/api/playnote.mdx @@ -9,11 +9,9 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Triggers the play of the given note. This will stop the any other current ongoing playback. -This method can be used in applications when individual notes need to be played for lesson or editor style purposes. -The player will not report any change in state or playback position during the playback of the requested note. +Triggers the play of the given note. This will stop the any other current ongoing playback. +This method can be used in applications when individual notes need to be played for lesson or editor style purposes. +The player will not report any change in state or playback position during the playback of the requested note. It is a playback of audio separate to the main song playback. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playNote(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0].notes[0]); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playNote(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0].notes[0]); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayNote(api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].Notes[0]); +```cs +var api = new AlphaTabApi(...); +api.PlayNote(api.Score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].Notes[0]); ``` -```kotlin -val api = AlphaTabApi(...) -api.playNote(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0].notes[0]); +```kotlin +val api = AlphaTabApi(...) +api.playNote(api.score.tracks[0].staves[0].bars[0].voices[0].beats[0].notes[0]); ``` diff --git a/docs/reference/api/playpause.mdx b/docs/reference/api/playpause.mdx index 43af287..88a7ea3 100644 --- a/docs/reference/api/playpause.mdx +++ b/docs/reference/api/playpause.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Toggles between play/pause depending on the current player state. If the player was playing, it will pause. If it is paused, it will initiate a play. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.playPause(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.playPause(); ``` -```cs -var api = new AlphaTabApi(...); -api.PlayPause(); +```cs +var api = new AlphaTabApi(...); +api.PlayPause(); ``` -```kotlin -val api = AlphaTabApi(...) -api.playPause() +```kotlin +val api = AlphaTabApi(...) +api.playPause() ``` diff --git a/docs/reference/api/postrenderfinished.mdx b/docs/reference/api/postrenderfinished.mdx index d94cb5a..99e2b6e 100644 --- a/docs/reference/api/postrenderfinished.mdx +++ b/docs/reference/api/postrenderfinished.mdx @@ -9,13 +9,11 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when the rendering of the whole music sheet is finished, and all handlers of `renderFinished` ran. If is enabled not all partial images of the music sheet might be rendered. -In this case the `renderFinished` event rather represents that the whole music sheet has been layouted and arranged -and every partial image can be requested for rendering. If you neeed more fine-grained access -to the actual layouting and rendering progress, you need to look at the low-level apis and - accessible via . +This event is fired when the rendering of the whole music sheet is finished, and all handlers of `renderFinished` ran. If CoreSettings.enableLazyLoading is enabled not all partial images of the music sheet might be rendered. +In this case the `renderFinished` event rather represents that the whole music sheet has been layouted and arranged +and every partial image can be requested for rendering. If you neeed more fine-grained access +to the actual layouting and rendering progress, you need to look at the low-level apis partialLayoutFinished and +partialRenderFinished accessible via renderer . -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.postRenderFinished.on(() => { - hideLoadingIndicator(); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.postRenderFinished.on(() => { + hideLoadingIndicator(); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.PostRenderFinished.On(() => -{ - HideLoadingIndicator(); -}); +```cs +var api = new AlphaTabApi(...); +api.PostRenderFinished.On(() => +{ + HideLoadingIndicator(); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.postRenderFinished.on { - hideLoadingIndicator(); -} +```kotlin +val api = AlphaTabApi(...) +api.postRenderFinished.on { + hideLoadingIndicator(); +} ``` diff --git a/docs/reference/api/print.mdx b/docs/reference/api/print.mdx index 7cda270..c1630ee 100644 --- a/docs/reference/api/print.mdx +++ b/docs/reference/api/print.mdx @@ -10,15 +10,13 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Opens a popup window with the rendered music notation for printing. Opens a popup window with the rendered music notation for printing. The default display of alphaTab in the browser is not very -suitable for printing. The items are lazy loaded, the width can be dynamic, and the scale might be better suitable for screens. -This function opens a popup window which is filled with a by-default A4 optimized view of the rendered score: - -* Lazy loading is disabled -* The scale is reduced to 0.8 -* The stretch force is reduced to 0.8 +Opens a popup window with the rendered music notation for printing. Opens a popup window with the rendered music notation for printing. The default display of alphaTab in the browser is not very +suitable for printing. The items are lazy loaded, the width can be dynamic, and the scale might be better suitable for screens. +This function opens a popup window which is filled with a by-default A4 optimized view of the rendered score: + +* Lazy loading is disabled +* The scale is reduced to 0.8 +* The stretch force is reduced to 0.8 * The width is optimized to A4. Portrait if the page-layout is used, landscape if the horizontal-layout is used. - -### Description Initiates a re-rendering of the current setup. If rendering is not yet possible, it will be deferred until the UI changes to be ready for rendering. + + + + + + + + + + + + + +
ParameterSummary
+ + + Additional hints to respect during layouting and rendering. +
## Examples @@ -31,21 +47,21 @@ Initiates a re-rendering of the current setup. If rendering is not yet possible, ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.render(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.render(); ``` -```cs -var api = new AlphaTabApi(...); -api.Render(); +```cs +var api = new AlphaTabApi(...); +api.Render(); ``` -```kotlin -val api = AlphaTabApi(...) -api.render() +```kotlin +val api = AlphaTabApi(...) +api.render() ``` diff --git a/docs/reference/api/renderer.mdx b/docs/reference/api/renderer.mdx index 834e5e5..ee2bded 100644 --- a/docs/reference/api/renderer.mdx +++ b/docs/reference/api/renderer.mdx @@ -10,10 +10,8 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The score renderer used for rendering the music sheet. This is the low-level API responsible for the actual rendering engine. -Gets access to the underling that is used for the rendering. +The score renderer used for rendering the music sheet. This is the low-level API responsible for the actual rendering engine. +Gets access to the underling IScoreRenderer that is used for the rendering. - -### Description -This event is fired when the rendering of the whole music sheet is finished. This event is fired when the rendering of the whole music sheet is finished from the render engine side. There might be still tasks open for +This event is fired when the rendering of the whole music sheet is finished. This event is fired when the rendering of the whole music sheet is finished from the render engine side. There might be still tasks open for the display component to visually display the rendered components when this event is notified (e.g. resizing of DOM elements are done). -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.renderFinished.on(() => { - updateProgressBar("Finishing"); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.renderFinished.on(() => { + updateProgressBar("Finishing"); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.RenderFinished.On(() => -{ - UpdateProgressBar("Finishing"); -}); +```cs +var api = new AlphaTabApi(...); +api.RenderFinished.On(() => +{ + UpdateProgressBar("Finishing"); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.renderFinished.on { - updateProgressBar("Finishing") -} +```kotlin +val api = AlphaTabApi(...) +api.renderFinished.on { + updateProgressBar("Finishing") +} ``` diff --git a/docs/reference/api/renderscore.mdx b/docs/reference/api/renderscore.mdx index c95b685..c7f2c1d 100644 --- a/docs/reference/api/renderscore.mdx +++ b/docs/reference/api/renderscore.mdx @@ -9,14 +9,12 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Initiates a rendering of the given score. "],["token","?"],["whitespace"," "],["identifier","trackIndexes"],["token",")"]]} - kotlin={[["identifier","fun"],["whitespace"," "],["identifier","renderScore"],["token","("],["identifier","score"],["token",":"],["whitespace"," "],["identifier","Score","/docs/reference/types/model/score"],["token",","],["whitespace"," "],["identifier","trackIndexes"],["token",":"],["whitespace"," "],["identifier","alphaTab.collections.DoubleList"],["token","?"],["token",")"],["token",":"],["whitespace"," "],["identifier","Unit"]]} + js={[["identifier","renderScore"],["token","("],["identifier","score"],["token",":"],["whitespace"," "],["identifier","Score","/docs/reference/types/model/score"],["token",","],["whitespace"," "],["identifier","trackIndexes"],["token","?"],["token",":"],["whitespace"," "],["identifier","number"],["token","[]"],["token",","],["whitespace"," "],["identifier","renderHints"],["token","?"],["token",":"],["whitespace"," "],["identifier","RenderHints","/docs/reference/types/rendering/renderhints"],["token",")"],["token",":"],["whitespace"," "],["identifier","void"]]} + csharp={[["keyword","void"],["whitespace"," "],["identifier","RenderScore"],["token","("],["identifier","Score","/docs/reference/types/model/score"],["whitespace"," "],["identifier","score"],["token",","],["whitespace"," "],["identifier","IList","https://learn.microsoft.com/en-us/dotnet/api/system.collections.ilist"],["token","<"],["identifier","double"],["token",">"],["token","?"],["whitespace"," "],["identifier","trackIndexes"],["token",","],["whitespace"," "],["identifier","RenderHints","/docs/reference/types/rendering/renderhints"],["token","?"],["whitespace"," "],["identifier","renderHints"],["token",")"]]} + kotlin={[["identifier","fun"],["whitespace"," "],["identifier","renderScore"],["token","("],["identifier","score"],["token",":"],["whitespace"," "],["identifier","Score","/docs/reference/types/model/score"],["token",","],["whitespace"," "],["identifier","trackIndexes"],["token",":"],["whitespace"," "],["identifier","alphaTab.collections.DoubleList"],["token","?"],["token",","],["whitespace"," "],["identifier","renderHints"],["token",":"],["whitespace"," "],["identifier","RenderHints","/docs/reference/types/rendering/renderhints"],["token","?"],["token",")"],["token",":"],["whitespace"," "],["identifier","Unit"]]} /> @@ -40,9 +38,17 @@ Initiates a rendering of the given score. + + + +
- The indexes of the tracks from the song that should be rendered. If not provided, the first track of the + The indexes of the tracks from the song that should be rendered. If not provided, the first track of the song will be shown.
+ + + Additional hints to respect during layouting and rendering. +
@@ -58,21 +64,21 @@ Initiates a rendering of the given score. ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.RenderScore(generateScore(),[ 2, 3 ]); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.RenderScore(generateScore(),[ 2, 3 ]); ``` -```cs -var api = new AlphaTabApi(...); -api.RenderScore(GenerateScore(), new double[] { 2, 3 }); +```cs +var api = new AlphaTabApi(...); +api.RenderScore(GenerateScore(), new double[] { 2, 3 }); ``` -```kotlin -val api = AlphaTabApi(...) -api.renderScore(generateScore(), alphaTab.collections.DoubleList(2, 3)); +```kotlin +val api = AlphaTabApi(...) +api.renderScore(generateScore(), alphaTab.collections.DoubleList(2, 3)); ``` diff --git a/docs/reference/api/renderstarted.mdx b/docs/reference/api/renderstarted.mdx index 95959e4..a3ce782 100644 --- a/docs/reference/api/renderstarted.mdx +++ b/docs/reference/api/renderstarted.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the rendering of the whole music sheet is starting. All preparations are completed and the layout and render sequence is about to start. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.renderStarted.on(() => { - updateProgressBar("Rendering"); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.renderStarted.on(() => { + updateProgressBar("Rendering"); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.RenderStarted.On(resized => -{ - UpdateProgressBar("Rendering"); -}); +```cs +var api = new AlphaTabApi(...); +api.RenderStarted.On(resized => +{ + UpdateProgressBar("Rendering"); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.renderStarted.on { resized -> - updateProgressBar("Rendering"); -} +```kotlin +val api = AlphaTabApi(...) +api.renderStarted.on { resized -> + updateProgressBar("Rendering"); +} ``` diff --git a/docs/reference/api/rendertracks.mdx b/docs/reference/api/rendertracks.mdx index bdb0c56..624f84a 100644 --- a/docs/reference/api/rendertracks.mdx +++ b/docs/reference/api/rendertracks.mdx @@ -9,14 +9,12 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Renders the given list of tracks. "],["whitespace"," "],["identifier","tracks"],["token",")"]]} - kotlin={[["identifier","fun"],["whitespace"," "],["identifier","renderTracks"],["token","("],["identifier","tracks"],["token",":"],["whitespace"," "],["identifier","alphaTab.collections.List"],["token","<"],["identifier","Track","/docs/reference/types/model/track"],["token",">"],["token",")"],["token",":"],["whitespace"," "],["identifier","Unit"]]} + js={[["identifier","renderTracks"],["token","("],["identifier","tracks"],["token",":"],["whitespace"," "],["identifier","Track","/docs/reference/types/model/track"],["token","[]"],["token",","],["whitespace"," "],["identifier","renderHints"],["token","?"],["token",":"],["whitespace"," "],["identifier","RenderHints","/docs/reference/types/rendering/renderhints"],["token",")"],["token",":"],["whitespace"," "],["identifier","void"]]} + csharp={[["keyword","void"],["whitespace"," "],["identifier","RenderTracks"],["token","("],["identifier","IList","https://learn.microsoft.com/en-us/dotnet/api/system.collections.ilist"],["token","<"],["identifier","Track","/docs/reference/types/model/track"],["token",">"],["whitespace"," "],["identifier","tracks"],["token",","],["whitespace"," "],["identifier","RenderHints","/docs/reference/types/rendering/renderhints"],["token","?"],["whitespace"," "],["identifier","renderHints"],["token",")"]]} + kotlin={[["identifier","fun"],["whitespace"," "],["identifier","renderTracks"],["token","("],["identifier","tracks"],["token",":"],["whitespace"," "],["identifier","alphaTab.collections.List"],["token","<"],["identifier","Track","/docs/reference/types/model/track"],["token",">"],["token",","],["whitespace"," "],["identifier","renderHints"],["token",":"],["whitespace"," "],["identifier","RenderHints","/docs/reference/types/rendering/renderhints"],["token","?"],["token",")"],["token",":"],["whitespace"," "],["identifier","Unit"]]} /> @@ -34,6 +32,14 @@ Renders the given list of tracks. + + + +
The tracks to render. They must all belong to the same score.
+ + + Additional hints to respect during layouting and rendering. +
@@ -49,27 +55,27 @@ Renders the given list of tracks. ]} > -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.renderTracks([api.score.tracks[0], api.score.tracks[1]]); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.renderTracks([api.score.tracks[0], api.score.tracks[1]]); ``` -```cs -var api = new AlphaTabApi(...); -api.RenderTracks(new []{ - api.Score.Tracks[2], - api.Score.Tracks[3] -}); +```cs +var api = new AlphaTabApi(...); +api.RenderTracks(new []{ + api.Score.Tracks[2], + api.Score.Tracks[3] +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.renderTracks(alphaTab.collections.List( - api.score.tracks[2], - api.score.tracks[3] -} +```kotlin +val api = AlphaTabApi(...) +api.renderTracks(alphaTab.collections.List( + api.score.tracks[2], + api.score.tracks[3] +} ``` diff --git a/docs/reference/api/resetsoundfonts.mdx b/docs/reference/api/resetsoundfonts.mdx index 3130724..0b79b25 100644 --- a/docs/reference/api/resetsoundfonts.mdx +++ b/docs/reference/api/resetsoundfonts.mdx @@ -9,10 +9,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -Unloads all presets from previously loaded SoundFonts. This function resets the player internally to not have any SoundFont loaded anymore. This allows you to reduce the memory usage of the page -if multiple partial SoundFonts are loaded via `loadSoundFont(..., true)`. Depending on the workflow you might also just want to use `loadSoundFont(..., false)` once +Unloads all presets from previously loaded SoundFonts. This function resets the player internally to not have any SoundFont loaded anymore. This allows you to reduce the memory usage of the page +if multiple partial SoundFonts are loaded via `loadSoundFont(..., true)`. Depending on the workflow you might also just want to use `loadSoundFont(..., false)` once instead of unloading the previous SoundFonts. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.loadSoundFont('/assets/guitars.sf2', true); -api.loadSoundFont('/assets/pianos.sf2', true); -// .. -api.resetSoundFonts(); -api.loadSoundFont('/assets/synths.sf2', true); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.loadSoundFont('/assets/guitars.sf2', true); +api.loadSoundFont('/assets/pianos.sf2', true); +// .. +api.resetSoundFonts(); +api.loadSoundFont('/assets/synths.sf2', true); ``` -```cs -var api = new AlphaTabApi(...); -api.LoadSoundFont(System.IO.File.OpenRead("guitars.sf2"), true); -api.LoadSoundFont(System.IO.File.OpenRead("pianos.sf2"), true); -... -api.ResetSoundFonts(); -api.LoadSoundFont(System.IO.File.OpenRead("synths.sf2"), true); +```cs +var api = new AlphaTabApi(...); +api.LoadSoundFont(System.IO.File.OpenRead("guitars.sf2"), true); +api.LoadSoundFont(System.IO.File.OpenRead("pianos.sf2"), true); +... +api.ResetSoundFonts(); +api.LoadSoundFont(System.IO.File.OpenRead("synths.sf2"), true); ``` -```kotlin -val api = AlphaTabApi(...) -api.loadSoundFont(readResource("guitars.sf2"), true) -api.loadSoundFont(readResource("pianos.sf2"), true) -... -api.resetSoundFonts() -api.loadSoundFont(readResource("synths.sf2"), true) +```kotlin +val api = AlphaTabApi(...) +api.loadSoundFont(readResource("guitars.sf2"), true) +api.loadSoundFont(readResource("pianos.sf2"), true) +... +api.resetSoundFonts() +api.loadSoundFont(readResource("synths.sf2"), true) ``` diff --git a/docs/reference/api/resize.mdx b/docs/reference/api/resize.mdx index ab7287b..ccd1dfe 100644 --- a/docs/reference/api/resize.mdx +++ b/docs/reference/api/resize.mdx @@ -9,10 +9,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired when alphaTab was resized and is about to rerender the music notation. This event is fired when alphaTab was resized and is about to rerender the music notation. Before the re-rendering on resize -the settings will be updated in the related components. This means that any changes to the layout options or other display settings are +This event is fired when alphaTab was resized and is about to rerender the music notation. This event is fired when alphaTab was resized and is about to rerender the music notation. Before the re-rendering on resize +the settings will be updated in the related components. This means that any changes to the layout options or other display settings are considered. This allows to implement scenarios where maybe the scale or the layout mode dynamically changes along the resizing. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.resize.on((args) => { - args.settings.scale = args.newWidth > 1300 - ? 1.5 - : (args.newWidth > 800) ? 1.3 : 1; -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.resize.on((args) => { + args.settings.scale = args.newWidth > 1300 + ? 1.5 + : (args.newWidth > 800) ? 1.3 : 1; +}); ``` -```cs -var api = new AlphaTabApi(...); -api.Resize.On(args => -{ - args.Settings.Display.Scale = args.NewWidth > 1300 - ? 1.5 - : (args.NewWidth > 800) ? 1.3 : 1; -}); +```cs +var api = new AlphaTabApi(...); +api.Resize.On(args => +{ + args.Settings.Display.Scale = args.NewWidth > 1300 + ? 1.5 + : (args.NewWidth > 800) ? 1.3 : 1; +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.resize.on { args -> - args.settings.display.scale = args.newWidth > 1300 - ? 1.5 - : (args.newWidth > 800) ? 1.3 : 1; -}); +```kotlin +val api = AlphaTabApi(...) +api.resize.on { args -> + args.settings.display.scale = args.newWidth > 1300 + ? 1.5 + : (args.newWidth > 800) ? 1.3 : 1; +}); ``` diff --git a/docs/reference/api/score.mdx b/docs/reference/api/score.mdx index 8b25460..74693ae 100644 --- a/docs/reference/api/score.mdx +++ b/docs/reference/api/score.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The score holding all information about the song being rendered -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -updateScoreInfo(api.score); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +updateScoreInfo(api.score); ``` -```cs -var api = new AlphaTabApi(...); -UpdateScoreInfo(api.Score); +```cs +var api = new AlphaTabApi(...); +UpdateScoreInfo(api.Score); ``` -```kotlin -val api = AlphaTabApi(...) -updateScoreInfo(api.score) +```kotlin +val api = AlphaTabApi(...) +updateScoreInfo(api.score) ``` diff --git a/docs/reference/api/scoreloaded.mdx b/docs/reference/api/scoreloaded.mdx index c1c0f61..b84cb3c 100644 --- a/docs/reference/api/scoreloaded.mdx +++ b/docs/reference/api/scoreloaded.mdx @@ -9,10 +9,8 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description -This event is fired whenever a new song is loaded. This event is fired whenever a new song is loaded or changing due to or calls. -It is fired after the transposition midi pitches from the settings were applied, but before any midi is generated or rendering is started. +This event is fired whenever a new song is loaded. This event is fired whenever a new song is loaded or changing due to renderScore or renderTracks calls. +It is fired after the transposition midi pitches from the settings were applied, but before any midi is generated or rendering is started. This allows any modification of the score before further processing. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.scoreLoaded.on((score) => { - updateSongInformationInUi(score); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.scoreLoaded.on((score) => { + updateSongInformationInUi(score); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.ScoreLoaded.On(score => -{ - UpdateSongInformationInUi(score); -}); +```cs +var api = new AlphaTabApi(...); +api.ScoreLoaded.On(score => +{ + UpdateSongInformationInUi(score); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.scoreLoaded.on { score -> - updateSongInformationInUi(score) -} +```kotlin +val api = AlphaTabApi(...) +api.scoreLoaded.on { score -> + updateSongInformationInUi(score) +} ``` diff --git a/docs/reference/api/scrolltocursor.mdx b/docs/reference/api/scrolltocursor.mdx index af6e90f..88a54d6 100644 --- a/docs/reference/api/scrolltocursor.mdx +++ b/docs/reference/api/scrolltocursor.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Initiates a scroll to the cursor. - -### Description -Changes the output device which should be used for playing the audio (player must be enabled). Use to load the list of available devices. - +Changes the output device which should be used for playing the audio (player must be enabled). Use enumerateOutputDevices to load the list of available devices. + In the web version this functionality relies on experimental APIs and might not yet be available in all browsers. https://caniuse.com/mdn-api_audiocontext_sinkid -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -const devices = await api.enumerateOutputDevices(); - -buildDeviceSelector(devices, async selectedDevice => { - await api.setOutputDevice(selectedDevice); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +const devices = await api.enumerateOutputDevices(); + +buildDeviceSelector(devices, async selectedDevice => { + await api.setOutputDevice(selectedDevice); +}); ``` -```cs -var api = new AlphaTabApi(...); -var devices = await api.EnumerateOutputDevices(); - -BuildDeviceSelector(devices, async selectedDevice => { - await api.SetOutputDevice(selectedDevice); -}); +```cs +var api = new AlphaTabApi(...); +var devices = await api.EnumerateOutputDevices(); + +BuildDeviceSelector(devices, async selectedDevice => { + await api.SetOutputDevice(selectedDevice); +}); ``` -```kotlin -fun init() = kotlinx.coroutines.runBlocking { - val api = AlphaTabApi(...) - val devices = api.enumerateOutputDevices().await() - - buildDeviceSelector(devices, fun (selectedDevice) { - suspend { - await api.setOutputDevice(selectedDevice) - } - }); -} +```kotlin +fun init() = kotlinx.coroutines.runBlocking { + val api = AlphaTabApi(...) + val devices = api.enumerateOutputDevices().await() + + buildDeviceSelector(devices, fun (selectedDevice) { + suspend { + await api.setOutputDevice(selectedDevice) + } + }); +} ``` diff --git a/docs/reference/api/settings.mdx b/docs/reference/api/settings.mdx index 562f66b..16c35d2 100644 --- a/docs/reference/api/settings.mdx +++ b/docs/reference/api/settings.mdx @@ -10,9 +10,7 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The settings that are used for rendering the music notation. Gets access to the underling object that is currently used by alphaTab. +The settings that are used for rendering the music notation. Gets access to the underling Settings object that is currently used by alphaTab. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -showSettingsModal(api.settings); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +showSettingsModal(api.settings); ``` -```cs -var api = new AlphaTabApi(...); -ShowSettingsDialog(api.Settings); +```cs +var api = new AlphaTabApi(...); +ShowSettingsDialog(api.Settings); ``` -```kotlin -val api = AlphaTabApi(...) -showSettingsDialog(api.settings) +```kotlin +val api = AlphaTabApi(...) +showSettingsDialog(api.settings) ``` diff --git a/docs/reference/api/settingsupdated.mdx b/docs/reference/api/settingsupdated.mdx index ac22e9d..8316b27 100644 --- a/docs/reference/api/settingsupdated.mdx +++ b/docs/reference/api/settingsupdated.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when a settings update was requested. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.settingsUpdated.on(() => { - updateSettingsUI(api.settings); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.settingsUpdated.on(() => { + updateSettingsUI(api.settings); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.SettingsUpdated.On(() => -{ - UpdateSettingsUI(api.settings); -}); +```cs +var api = new AlphaTabApi(...); +api.SettingsUpdated.On(() => +{ + UpdateSettingsUI(api.settings); +}); ``` -```kotlin -val api = AlphaTabApi(...) -api.SettingsUpdated.on { - updateSettingsUI(api.settings) -} +```kotlin +val api = AlphaTabApi(...) +api.SettingsUpdated.on { + updateSettingsUI(api.settings) +} ``` diff --git a/docs/reference/api/soundfontload.mdx b/docs/reference/api/soundfontload.mdx index fc43611..b58e575 100644 --- a/docs/reference/api/soundfontload.mdx +++ b/docs/reference/api/soundfontload.mdx @@ -10,8 +10,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the SoundFont is being loaded. This event is fired when the SoundFont is being loaded and reports the progress accordingly. { - updateProgress(e.loaded, e.total); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.soundFontLoad.on((e) => { + updateProgress(e.loaded, e.total); +}); ``` diff --git a/docs/reference/api/soundfontloaded.mdx b/docs/reference/api/soundfontloaded.mdx index 9de8fe2..6ca9b1f 100644 --- a/docs/reference/api/soundfontloaded.mdx +++ b/docs/reference/api/soundfontloaded.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description This event is fired when the SoundFont needed for playback was loaded. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.soundFontLoaded.on(() => { - hideSoundFontLoadingIndicator(); -}); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.soundFontLoaded.on(() => { + hideSoundFontLoadingIndicator(); +}); ``` -```cs -var api = new AlphaTabApi(...); -api.SoundFontLoaded.On(() => -{ - HideSoundFontLoadingIndicator(); -}); +```cs +var api = new AlphaTabApi(...); +api.SoundFontLoaded.On(() => +{ + HideSoundFontLoadingIndicator(); +}); ``` -```kotlin -val api = AlphaTabApi(...); -api.soundFontLoaded.on { - hideSoundFontLoadingIndicator(); -} +```kotlin +val api = AlphaTabApi(...); +api.soundFontLoaded.on { + hideSoundFontLoadingIndicator(); +} ``` diff --git a/docs/reference/api/stop.mdx b/docs/reference/api/stop.mdx index e51f12c..a0ccb98 100644 --- a/docs/reference/api/stop.mdx +++ b/docs/reference/api/stop.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Stops the playback of the current song, and moves the playback position back to the start. If a dedicated playback range is selected, it will move the playback position to the start of this range, not the whole song. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.stop(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.stop(); ``` -```cs -var api = new AlphaTabApi(...); -api.Stop(); +```cs +var api = new AlphaTabApi(...); +api.Stop(); ``` -```kotlin -val api = AlphaTabApi(...) -api.stop() +```kotlin +val api = AlphaTabApi(...) +api.stop() ``` diff --git a/docs/reference/api/tex.mdx b/docs/reference/api/tex.mdx index e846b00..41eeea2 100644 --- a/docs/reference/api/tex.mdx +++ b/docs/reference/api/tex.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Tells alphaTab to render the given alphaTex. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.tex("\\title 'Test' . 3.3.4"); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.tex("\\title 'Test' . 3.3.4"); ``` -```cs -var api = new AlphaTabApi(...); -api.Tex("\\title 'Test' . 3.3.4"); +```cs +var api = new AlphaTabApi(...); +api.Tex("\\title 'Test' . 3.3.4"); ``` -```kotlin -val api = AlphaTabApi(...) -api.tex("\\title 'Test' . 3.3.4"); +```kotlin +val api = AlphaTabApi(...) +api.tex("\\title 'Test' . 3.3.4"); ``` diff --git a/docs/reference/api/tickcache.mdx b/docs/reference/api/tickcache.mdx index 19b6b74..f21bee9 100644 --- a/docs/reference/api/tickcache.mdx +++ b/docs/reference/api/tickcache.mdx @@ -10,13 +10,11 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The tick cache allowing lookup of midi ticks to beats. Gets the tick cache allowing lookup of midi ticks to beats. If the player is enabled, a midi file will be generated -for the loaded for later playback. During this generation this tick cache is filled with the -exact midi ticks when beats are played. - -The method allows a lookup of the beat related to a given input midi tick. +The tick cache allowing lookup of midi ticks to beats. Gets the tick cache allowing lookup of midi ticks to beats. If the player is enabled, a midi file will be generated +for the loaded Score for later playback. During this generation this tick cache is filled with the +exact midi ticks when beats are played. + +The findBeat method allows a lookup of the beat related to a given input midi tick. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -const lookupResult = api.tickCache.findBeat(new Set([0, 1]), 100); -const currentBeat = lookupResult?.currentBeat; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +const lookupResult = api.tickCache.findBeat(new Set([0, 1]), 100); +const currentBeat = lookupResult?.currentBeat; ``` -```cs -var api = new AlphaTabApi(...); -var lookupResult = api.TickCache.FindBeat(new AlphaTab.Core.EcmaScript.Set(0, 1), 100); -var currentBeat = lookupResult?.CurrentBeat; +```cs +var api = new AlphaTabApi(...); +var lookupResult = api.TickCache.FindBeat(new AlphaTab.Core.EcmaScript.Set(0, 1), 100); +var currentBeat = lookupResult?.CurrentBeat; ``` -```kotlin -val api = AlphaTabApi(...) -val lookupResult = api.tickCache.findBeat(alphaTab.core.ecmaScript.Set(0, 1), 100); -val currentBeat = lookupResult?.CurrentBeat; +```kotlin +val api = AlphaTabApi(...) +val lookupResult = api.tickCache.findBeat(alphaTab.core.ecmaScript.Set(0, 1), 100); +val currentBeat = lookupResult?.CurrentBeat; ``` diff --git a/docs/reference/api/tickposition.mdx b/docs/reference/api/tickposition.mdx index b3e6f35..f2f09a7 100644 --- a/docs/reference/api/tickposition.mdx +++ b/docs/reference/api/tickposition.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The position within the song in midi ticks. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.tickPosition = 4000; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.tickPosition = 4000; ``` -```cs -var api = new AlphaTabApi(...); -api.TickPosition = 4000; +```cs +var api = new AlphaTabApi(...); +api.TickPosition = 4000; ``` -```kotlin -val api = AlphaTabApi(...) -api.tickPosition = 4000 +```kotlin +val api = AlphaTabApi(...) +api.tickPosition = 4000 ``` diff --git a/docs/reference/api/timeposition.mdx b/docs/reference/api/timeposition.mdx index 83985b4..ce700d5 100644 --- a/docs/reference/api/timeposition.mdx +++ b/docs/reference/api/timeposition.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The position within the song in milliseconds -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.timePosition = 4000; +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.timePosition = 4000; ``` -```cs -var api = new AlphaTabApi(...); -api.TimePosition = 4000; +```cs +var api = new AlphaTabApi(...); +api.TimePosition = 4000; ``` -```kotlin -val api = AlphaTabApi(...) -api.timePosition = 4000 +```kotlin +val api = AlphaTabApi(...) +api.timePosition = 4000 ``` diff --git a/docs/reference/api/tracks.mdx b/docs/reference/api/tracks.mdx index c6ea29b..79d6ff0 100644 --- a/docs/reference/api/tracks.mdx +++ b/docs/reference/api/tracks.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The list of the tracks that are currently rendered. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -highlightCurrentTracksInTrackSelector(api.tracks); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +highlightCurrentTracksInTrackSelector(api.tracks); ``` -```cs -var api = new AlphaTabApi(...); -HighlightCurrentTracksInTrackSelector(api.Tracks); +```cs +var api = new AlphaTabApi(...); +HighlightCurrentTracksInTrackSelector(api.Tracks); ``` -```kotlin -val api = AlphaTabApi(...) -highlightCurrentTracksInTrackSelector(api.tracks) +```kotlin +val api = AlphaTabApi(...) +highlightCurrentTracksInTrackSelector(api.tracks) ``` diff --git a/docs/reference/api/uifacade.mdx b/docs/reference/api/uifacade.mdx index 2695d31..1b4ddd8 100644 --- a/docs/reference/api/uifacade.mdx +++ b/docs/reference/api/uifacade.mdx @@ -10,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The UI facade used for interacting with the user interface (like the browser). The implementation depends on the platform alphaTab is running in (e.g. the web version in the browser, WPF in .net etc.) - -### Description -Applies any changes that were done to the settings object. It also informs the about any new values to consider. -By default alphaTab will not trigger any re-rendering or settings update just if the settings object itself was changed. This method must be called -to trigger an update of the settings in all components. Then a re-rendering can be initiated using the method. +Applies any changes that were done to the settings object. It also informs the renderer about any new values to consider. +By default alphaTab will not trigger any re-rendering or settings update just if the settings object itself was changed. This method must be called +to trigger an update of the settings in all components. Then a re-rendering can be initiated using the render method. -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); -api.settings.display.scale = 2.0; -api.updateSettings(); -api.render(); +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab')); +api.settings.display.scale = 2.0; +api.updateSettings(); +api.render(); ``` -```cs -var api = new AlphaTabApi(...); - -api.Settings.Display.Scale = 2.0; -api.UpdateSettings(); -api.Render() +```cs +var api = new AlphaTabApi(...); + +api.Settings.Display.Scale = 2.0; +api.UpdateSettings(); +api.Render() ``` -```kotlin -val api = AlphaTabApi(...) - -api.settings.display.scale = 2.0 -api.updateSettings() -api.render() +```kotlin +val api = AlphaTabApi(...) + +api.settings.display.scale = 2.0 +api.updateSettings() +api.render() ``` diff --git a/docs/reference/api/updatesyncpoints.mdx b/docs/reference/api/updatesyncpoints.mdx index f612a6b..515c372 100644 --- a/docs/reference/api/updatesyncpoints.mdx +++ b/docs/reference/api/updatesyncpoints.mdx @@ -9,8 +9,6 @@ sidebar_custom_props: import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature } from '@site/src/reference-commons' - -### Description Triggers an update of the sync points for the current score after modification within the data model - -### Description -Enables lazy loading of the rendered music sheet chunks. AlphaTab renders the music sheet in smaller sub-chunks to have fast UI feedback. Not all of those sub-chunks are immediately -appended to the DOM due to performance reasons. AlphaTab tries to detect which elements are visible on the screen, and only -appends those elements to the DOM. This reduces the load of the browser heavily but is not working for all layouts and use cases. -This setting set to false, ensures that all rendered items are instantly appended to the DOM. +Enables lazy loading of the rendered music sheet chunks. AlphaTab renders the music sheet in smaller sub-chunks to have fast UI feedback. Not all of those sub-chunks are immediately +appended to the DOM due to performance reasons. AlphaTab tries to detect which elements are visible on the screen, and only +appends those elements to the DOM. This reduces the load of the browser heavily but is not working for all layouts and use cases. +This setting set to false, ensures that all rendered items are instantly appended to the DOM. The lazy rendering of partial might not be available on all platforms. - -### Description -The engine which should be used to render the the tablature. AlphaTab can use various render engines to draw the music notation. The available render engines is specific to the platform. Please refer to the table below to find out which engines are available on which platform. -- `default`- Platform specific default engine -- `html5`- Uses HTML5 canvas elements to render the music notation (browser only) -- `svg`- Outputs SVG strings (all platforms, default for web) -- `skia` - Uses [Skia](https://skia.org/) for rendering (all non-browser platforms via [alphaSkia](https://github.com/CoderLine/alphaSkia), default for non-web) -- `gdi` - Uses [GDI+](https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/graphics-and-drawing-in-windows-forms) for rendering (only on .net) +The engine which should be used to render the the tablature. AlphaTab can use various render engines to draw the music notation. The available render engines is specific to the platform. Please refer to the table below to find out which engines are available on which platform. +- `default`- Platform specific default engine +- `html5`- Uses HTML5 canvas elements to render the music notation (browser only) +- `svg`- Outputs SVG strings (all platforms, default for web) +- `skia` - Uses [Skia](https://skia.org/) for rendering (all non-browser platforms via [alphaSkia](https://github.com/CoderLine/alphaSkia), default for non-web) +- `gdi` - Uses [GDI+](https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/graphics-and-drawing-in-windows-forms) for rendering (only on .net) - `android` - Uses [android.graphics.Canvas](https://developer.android.com/reference/android/graphics/Canvas) for rendering (only on Android) - -### Description -The full URL to the input file to be loaded. AlphaTab can automatically load and render a file after initialization. This eliminates the need of manually calling -one of the load methods which are available. alphaTab will automatically initiate an `XMLHttpRequest` after initialization +The full URL to the input file to be loaded. AlphaTab can automatically load and render a file after initialization. This eliminates the need of manually calling +one of the load methods which are available. alphaTab will automatically initiate an `XMLHttpRequest` after initialization to load and display the provided url of this setting. Note that this setting is only interpreted once on initialization. - -### Description -The full URL to the alphaTab font directory. AlphaTab will generate some dynamic CSS that is needed for displaying the music symbols correctly. For this it needs to know -where the Web Font files of [Bravura](https://github.com/steinbergmedia/bravura) are. Normally alphaTab expects -them to be in a `font` subfolder beside the script file. If this is not the case, this setting must be used to configure the path. -Alternatively also a global variable `ALPHATAB_FONT` can be set on the page before initializing alphaTab. - -Use for more flexible font configuration. +The full URL to the alphaTab font directory. AlphaTab will generate some dynamic CSS that is needed for displaying the music symbols correctly. For this it needs to know +where the Web Font files of [Bravura](https://github.com/steinbergmedia/bravura) are. Normally alphaTab expects +them to be in a `font` subfolder beside the script file. If this is not the case, this setting must be used to configure the path. +Alternatively also a global variable `ALPHATAB_FONT` can be set on the page before initializing alphaTab. + +Use smuflFontSources for more flexible font configuration. - -### Description -Whether in the also the position and area of each individual note is provided. AlphaTab collects the position of the rendered music notation elements during the rendering process. This way some level of interactivity can be provided like the feature that seeks to the corresponding position when clicking on a beat. +Whether in the BoundsLookup also the position and area of each individual note is provided. AlphaTab collects the position of the rendered music notation elements during the rendering process. This way some level of interactivity can be provided like the feature that seeks to the corresponding position when clicking on a beat. By default the position of the individual notes is not collected due to performance reasons. If access to note position information is needed, this setting can enable it. { - const lookup = api.renderer.boundsLookup; - const x = 100; - const y = 100; - const beat = lookup.getBeatAtPos(x, y); - const note = lookup.getNoteAtPos(beat, x, y); -}); +```js +const settings = new alphaTab.model.Settings(); +settings.core.includeNoteBounds = true; +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'), settings); +api.renderFinished.on(() => { + const lookup = api.renderer.boundsLookup; + const x = 100; + const y = 100; + const beat = lookup.getBeatAtPos(x, y); + const note = lookup.getNoteAtPos(beat, x, y); +}); ``` diff --git a/docs/reference/settings/core/loglevel.mdx b/docs/reference/settings/core/loglevel.mdx index 762b08c..99551f9 100644 --- a/docs/reference/settings/core/loglevel.mdx +++ b/docs/reference/settings/core/loglevel.mdx @@ -1,5 +1,6 @@ --- title: core.logLevel +sidebar_label: logLevel sidebar_custom_props: jsOnParent: true category: Core @@ -10,8 +11,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The log level to use within alphaTab AlphaTab internally does quite a bit of logging for debugging and informational purposes. The log level of alphaTab can be controlled via this setting. - -### Description -The full URL to the alphaTab JavaScript file. AlphaTab needs to know the full URL to the script file it is contained in to launch the web workers. AlphaTab will do its best to auto-detect -this path but in case it fails, this setting can be used to explicitly define it. Altenatively also a global variable `ALPHATAB_ROOT` can -be defined before initializing. Please be aware that bundling alphaTab together with other scripts might cause errors -in case those scripts are not suitable for web workers. e.g. if there is a script bundled together with alphaTab that accesses the DOM, +The full URL to the alphaTab JavaScript file. AlphaTab needs to know the full URL to the script file it is contained in to launch the web workers. AlphaTab will do its best to auto-detect +this path but in case it fails, this setting can be used to explicitly define it. Altenatively also a global variable `ALPHATAB_ROOT` can +be defined before initializing. Please be aware that bundling alphaTab together with other scripts might cause errors +in case those scripts are not suitable for web workers. e.g. if there is a script bundled together with alphaTab that accesses the DOM, this will cause an error when alphaTab starts this script as worker. - -### Description -Defines the URLs from which to load the SMuFL compliant font files. These sources will be used to load and register the webfonts on the page so -they are available for rendering the music sheet. The sources can be set to any -CSS compatible URL which can be passed into `url()`. -See https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src#url - -If you customize the SmuFL font used in alphaTab, you will also need to provide -the respective SMuFL Metadata information to alphaTab. -Set the metadata via on the rendering resources. +Defines the URLs from which to load the SMuFL compliant font files. These sources will be used to load and register the webfonts on the page so +they are available for rendering the music sheet. The sources can be set to any +CSS compatible URL which can be passed into `url()`. +See https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src#url + +If you customize the SmuFL font used in alphaTab, you will also need to provide +the respective SMuFL Metadata information to alphaTab. +Set the metadata via fillFromSmufl on the rendering resources. "],["whitespace"," "],["token","|"],["whitespace"," "],["keyword","null"],["whitespace"," "],["token","="],["whitespace"," "],["identifier","Bravura files located at ."],["token",";"]]} + js={[["identifier","smuflFontSources"],["token",":"],["whitespace"," "],["identifier","Map","/docs/reference/types/fontfileformat"],["token","<"],["identifier","FontFileFormat","/docs/reference/types/fontfileformat"],["token",","],["whitespace"," "],["identifier","string"],["token",">"],["whitespace"," "],["token","|"],["whitespace"," "],["keyword","null"],["whitespace"," "],["token","="],["whitespace"," "],["identifier","Bravura files located at fontDirectory ."],["token",";"]]} /> diff --git a/docs/reference/settings/core/tex.mdx b/docs/reference/settings/core/tex.mdx index e86987d..82a18a6 100644 --- a/docs/reference/settings/core/tex.mdx +++ b/docs/reference/settings/core/tex.mdx @@ -1,5 +1,6 @@ --- title: core.tex +sidebar_label: tex sidebar_custom_props: javaScriptOnly: true jsOnParent: true @@ -11,9 +12,7 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -Whether the contents of the DOM element should be loaded as alphaTex. This setting allows you to fill alphaTex code into the DOM element and make alphaTab automatically +Whether the contents of the DOM element should be loaded as alphaTex. This setting allows you to fill alphaTex code into the DOM element and make alphaTab automatically load it when initializing. Note that this setting is only interpreted once on initialization. \title "Simple alphaTex init" . 3.3*4 - +```html +
\title "Simple alphaTex init" . 3.3*4
+ ``` diff --git a/docs/reference/settings/core/tracks.mdx b/docs/reference/settings/core/tracks.mdx index a870eab..8b7e11b 100644 --- a/docs/reference/settings/core/tracks.mdx +++ b/docs/reference/settings/core/tracks.mdx @@ -1,5 +1,6 @@ --- title: core.tracks +sidebar_label: tracks sidebar_custom_props: javaScriptOnly: true jsOnParent: true @@ -11,9 +12,7 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The tracks to display for the initally loaded file. This setting can be used in combinition with the or option. It controls which of the tracks +The tracks to display for the initally loaded file. This setting can be used in combinition with the file or tex option. It controls which of the tracks of the initially loaded file should be displayed. - -### Description -Whether the rendering should be done in a worker if possible. AlphaTab normally tries to render the music sheet asynchronously in a worker. This reduces the load on the UI side and avoids hanging. However sometimes it might be more desirable to have +Whether the rendering should be done in a worker if possible. AlphaTab normally tries to render the music sheet asynchronously in a worker. This reduces the load on the UI side and avoids hanging. However sometimes it might be more desirable to have a synchronous rendering behavior. This setting can be set to false to synchronously render the music sheet on the UI side. - -### Description The padding between the accolade bar and the start of the bar itself. - -### Description -The total number of bars that should be rendered from the song. (-1 for all bars) This setting sets the number of bars that should be rendered from the overall song. This setting can be used to -achieve a paging system or to only show partial bars of the same file. By this a tutorial alike display can be achieved +The total number of bars that should be rendered from the song. (-1 for all bars) This setting sets the number of bars that should be rendered from the overall song. This setting can be used to +achieve a paging system or to only show partial bars of the same file. By this a tutorial alike display can be achieved that explains various parts of the song. [Demo](/docs/showcase/layouts) - -### Description -The number of bars that should be placed within one partial render. AlphaTab renders the whole music sheet in smaller chunks named "partials". This is to reduce the risk of -encountering browser performance restrictions and it gives faster visual feedback to the user. This +The number of bars that should be placed within one partial render. AlphaTab renders the whole music sheet in smaller chunks named "partials". This is to reduce the risk of +encountering browser performance restrictions and it gives faster visual feedback to the user. This setting controls how many bars are placed within such a partial. - -### Description -Limit the displayed bars per system (row). (-1 for automatic mode) This setting sets the number of bars that should be put into one row during layouting. This setting is only respected -when using the where bars are aligned in systems. [Demo](/docs/showcase/layouts#page-layout-5-bars-per-row). +Limit the displayed bars per system (row). (-1 for automatic mode) This setting sets the number of bars that should be put into one row during layouting. This setting is only respected +when using the Page where bars are aligned in systems. [Demo](/docs/showcase/layouts#page-layout-5-bars-per-row). - -### Description The padding between individual effect bands. - -### Description The bottom padding applied to effect annotation staffs. - -### Description The top padding applied to effect annotation staffs. + +The top padding applied to the first main notation staff (standard, tabs, numbered, slash). + + + diff --git a/docs/reference/settings/display/firststaffpaddingleft.mdx b/docs/reference/settings/display/firststaffpaddingleft.mdx index 7f697f8..ceacbbe 100644 --- a/docs/reference/settings/display/firststaffpaddingleft.mdx +++ b/docs/reference/settings/display/firststaffpaddingleft.mdx @@ -1,5 +1,6 @@ --- title: display.firstStaffPaddingLeft +sidebar_label: firstStaffPaddingLeft sidebar_custom_props: jsOnParent: true category: Display @@ -10,8 +11,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The left padding applied between the left line and the first glyph in the first staff in a system. - -### Description The top padding applied to first system. diff --git a/docs/reference/settings/display/justifylastsystem.mdx b/docs/reference/settings/display/justifylastsystem.mdx index 9b461fc..512dfd6 100644 --- a/docs/reference/settings/display/justifylastsystem.mdx +++ b/docs/reference/settings/display/justifylastsystem.mdx @@ -1,5 +1,6 @@ --- title: display.justifyLastSystem +sidebar_label: justifyLastSystem sidebar_custom_props: jsOnParent: true category: Display @@ -10,12 +11,10 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -Whether to justify also the last system in page layouts. Setting this option to `true` tells alphaTab to also justify the last system (row) like it -already does for the systems which are full. -| Justification Disabled | Justification Enabled | -|--------------------------------------------------------------|-------------------------------------------------------| +Whether to justify also the last system in page layouts. Setting this option to `true` tells alphaTab to also justify the last system (row) like it +already does for the systems which are full. +| Justification Disabled | Justification Enabled | +|--------------------------------------------------------------|-------------------------------------------------------| | ![Disabled](/img/reference/property/justify-last-system-false.png) | ![Enabled](/img/reference/property/justify-last-system-true.png) | + +The bottom padding applied to last main notation staff (standard, tabs, numbered, slash). + + + diff --git a/docs/reference/settings/display/lastsystempaddingbottom.mdx b/docs/reference/settings/display/lastsystempaddingbottom.mdx index d24d705..f93082e 100644 --- a/docs/reference/settings/display/lastsystempaddingbottom.mdx +++ b/docs/reference/settings/display/lastsystempaddingbottom.mdx @@ -1,5 +1,6 @@ --- title: display.lastSystemPaddingBottom +sidebar_label: lastSystemPaddingBottom sidebar_custom_props: jsOnParent: true category: Display @@ -10,13 +11,11 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The bottom padding applied to the last system. diff --git a/docs/reference/settings/display/layoutmode.mdx b/docs/reference/settings/display/layoutmode.mdx index 9f6d5da..8c9c0a0 100644 --- a/docs/reference/settings/display/layoutmode.mdx +++ b/docs/reference/settings/display/layoutmode.mdx @@ -1,5 +1,6 @@ --- title: display.layoutMode +sidebar_label: layoutMode sidebar_custom_props: jsOnParent: true category: Display @@ -10,8 +11,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The layouting mode used to arrange the the notation. AlphaTab has various layout engines that arrange the rendered bars differently. This setting controls which layout mode is used. + +The additional padding to apply between multiple lyric lines. + + + diff --git a/docs/reference/settings/display/notationstaffpaddingbottom.mdx b/docs/reference/settings/display/notationstaffpaddingbottom.mdx index b9d162a..069b1e6 100644 --- a/docs/reference/settings/display/notationstaffpaddingbottom.mdx +++ b/docs/reference/settings/display/notationstaffpaddingbottom.mdx @@ -1,5 +1,6 @@ --- title: display.notationStaffPaddingBottom +sidebar_label: notationStaffPaddingBottom sidebar_custom_props: jsOnParent: true category: Display @@ -10,13 +11,11 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The bottom padding applied to main notation staves (standard, tabs, numbered, slash). diff --git a/docs/reference/settings/display/notationstaffpaddingtop.mdx b/docs/reference/settings/display/notationstaffpaddingtop.mdx index 6100eca..08ad36d 100644 --- a/docs/reference/settings/display/notationstaffpaddingtop.mdx +++ b/docs/reference/settings/display/notationstaffpaddingtop.mdx @@ -1,5 +1,6 @@ --- title: display.notationStaffPaddingTop +sidebar_label: notationStaffPaddingTop sidebar_custom_props: jsOnParent: true category: Display @@ -10,13 +11,11 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -The bottom padding applied to main notation staves (standard, tabs, numbered, slash). +The top padding applied to main notation staves (standard, tabs, numbered, slash). diff --git a/docs/reference/settings/display/padding.mdx b/docs/reference/settings/display/padding.mdx index 3137e64..8e289ea 100644 --- a/docs/reference/settings/display/padding.mdx +++ b/docs/reference/settings/display/padding.mdx @@ -1,5 +1,6 @@ --- title: display.padding +sidebar_label: padding sidebar_custom_props: jsOnParent: true category: Display @@ -10,11 +11,9 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -Adjusts the padding between the music notation and the border. Adjusts the padding between the music notation and the outer border of the container element. -The array is either: -* 2 elements: `[left-right, top-bottom]` +Adjusts the padding between the music notation and the border. Adjusts the padding between the music notation and the outer border of the container element. +The array is either: +* 2 elements: `[left-right, top-bottom]` * 4 elements: ``[left, top, right, bottom]`` - -### Description -Allows adjusting of the used fonts and colors for rendering. AlphaTab allows configuring the colors and fonts used for rendering via the rendering resources settings. Please note that as of today -this is the primary way of changing the way how alphaTab styles elements. CSS styling in the browser cannot be guaranteed to work due to its flexibility. - - -Due to space reasons in the following table the common prefix of the settings are removed. Please refer to these examples to eliminate confusion on the usage: - -| Platform | Prefix | Example Usage | -|------------|---------------------------|--------------------------------------------------------------------| -| JavaScript | `display.resources.` | `settings.display.resources.wordsFont = ...` | -| JSON | `display.resources.` | `var settings = { display: { resources: { wordsFonts: '...'} } };` | -| JSON | `resources.` | `var settings = { resources: { wordsFonts: '...'} };` | -| .net | `Display.Resources.` | `settings.Display.Resources.WordsFonts = ...` | -| Android | `display.resources.` | `settings.display.resources.wordsFonts = ...` | -## Types - -### Fonts - -For the JavaScript platform any font that might be installed on the client machines can be used. -Any additional fonts can be added via WebFonts. The rendering of the score will be delayed until it is detected that the font was loaded. -Simply use any CSS font property compliant string as configuration. Relative font sizes with percentual values are not supported, remaining values will be considered if supported. - - Multiple fonts are also supported for the Web version. alphaTab will check if any of the fonts in the list is loaded instead of all. If none is available at the time alphaTab is initialized, it will try to initiate the load of the specified fonts individual through the Browser Font APIs. - -For the .net platform any installed font on the system can be used. Simply construct the `Font` object to configure your desired fonts. - -### Colors - -For JavaScript you can use any CSS font property compliant string. (#RGB, #RGBA, #RRGGBB, #RRGGBBAA, rgb(r,g,b), rgba(r,g,b,a) ) - +Allows adjusting of the used fonts and colors for rendering. AlphaTab allows configuring the colors and fonts used for rendering via the rendering resources settings. Please note that as of today +this is the primary way of changing the way how alphaTab styles elements. CSS styling in the browser cannot be guaranteed to work due to its flexibility. + + +Due to space reasons in the following table the common prefix of the settings are removed. Please refer to these examples to eliminate confusion on the usage: + +| Platform | Prefix | Example Usage | +|------------|---------------------------|--------------------------------------------------------------------| +| JavaScript | `display.resources.` | `settings.display.resources.wordsFont = ...` | +| JSON | `display.resources.` | `var settings = { display: { resources: { wordsFonts: '...'} } };` | +| JSON | `resources.` | `var settings = { resources: { wordsFonts: '...'} };` | +| .net | `Display.Resources.` | `settings.Display.Resources.WordsFonts = ...` | +| Android | `display.resources.` | `settings.display.resources.wordsFonts = ...` | +## Types + +### Fonts + +For the JavaScript platform any font that might be installed on the client machines can be used. +Any additional fonts can be added via WebFonts. The rendering of the score will be delayed until it is detected that the font was loaded. +Simply use any CSS font property compliant string as configuration. Relative font sizes with percentual values are not supported, remaining values will be considered if supported. + + Multiple fonts are also supported for the Web version. alphaTab will check if any of the fonts in the list is loaded instead of all. If none is available at the time alphaTab is initialized, it will try to initiate the load of the specified fonts individual through the Browser Font APIs. + +For the .net platform any installed font on the system can be used. Simply construct the `Font` object to configure your desired fonts. + +### Colors + +For JavaScript you can use any CSS font property compliant string. (#RGB, #RGBA, #RRGGBB, #RRGGBBAA, rgb(r,g,b), rgba(r,g,b,a) ) + On .net simply construct the `Color` object to configure your desired color. - -### Description -The zoom level of the rendered notation. AlphaTab can scale up or down the rendered music notation for more optimized display scenarios. By default music notation is rendered at 100% scale (value 1) and can be scaled up or down by +The zoom level of the rendered notation. AlphaTab can scale up or down the rendered music notation for more optimized display scenarios. By default music notation is rendered at 100% scale (value 1) and can be scaled up or down by percental values. - -### Description The left padding applied between the left line and the first glyph in the following staff in a system. - -### Description -The bar start index to start layouting with. This setting sets the index of the first bar that should be rendered from the overall song. This setting can be used to -achieve a paging system or to only show partial bars of the same file. By this a tutorial alike display can be achieved -that explains various parts of the song. Please note that this is the bar number as shown in the music sheet (1-based) not the array index (0-based). +The bar start index to start layouting with. This setting sets the index of the first bar that should be rendered from the overall song. This setting can be used to +achieve a paging system or to only show partial bars of the same file. By this a tutorial alike display can be achieved +that explains various parts of the song. Please note that this is the bar number as shown in the music sheet (1-based) not the array index (0-based). [Demo](/docs/showcase/layouts#page-layout-bar-5-to-8) - -### Description -The stave profile defining which staves are shown for the music sheet. AlphaTab has various stave profiles that define which staves will be shown in for the rendered tracks. Its recommended -to keep this on and rather rely on the options available ob level +The stave profile defining which staves are shown for the music sheet. AlphaTab has various stave profiles that define which staves will be shown in for the rendered tracks. Its recommended +to keep this on Default and rather rely on the options available ob Staff level - -### Description -The default stretch force to use for layouting. The stretch force is a setting that controls the spacing of the music notation. AlphaTab uses a varaint of the Gourlay algorithm for spacing which has springs and rods for -aligning elements. This setting controls the "strength" of the springs. The stronger the springs, the wider the spacing. - -| Force 1 | Force 0.5 | -|--------------------------------------------------------------|-------------------------------------------------------| +The default stretch force to use for layouting. The stretch force is a setting that controls the spacing of the music notation. AlphaTab uses a varaint of the Gourlay algorithm for spacing which has springs and rods for +aligning elements. This setting controls the "strength" of the springs. The stronger the springs, the wider the spacing. + +| Force 1 | Force 0.5 | +|--------------------------------------------------------------|-------------------------------------------------------| | ![Default](/img/reference/property/stretchforce-default.png) | ![0.5](/img/reference/property/stretchforce-half.png) | - -### Description The padding left to the track name label of the system. - -### Description The padding left to the track name label of the system. - -### Description The bottom padding applied to systems beside the last one. diff --git a/docs/reference/settings/display/systempaddingtop.mdx b/docs/reference/settings/display/systempaddingtop.mdx index 07cfc17..c6ef197 100644 --- a/docs/reference/settings/display/systempaddingtop.mdx +++ b/docs/reference/settings/display/systempaddingtop.mdx @@ -1,5 +1,6 @@ --- title: display.systemPaddingTop +sidebar_label: systemPaddingTop sidebar_custom_props: jsOnParent: true category: Display @@ -10,8 +11,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description The top padding applied systems beside the first one. - -### Description -The mode used to arrange staves and systems. By default alphaTab uses an own (automatic) mode to arrange and scale the bars when -putting them into staves. This property allows changing this mode to change the music sheet arrangement. - -## Supported File Formats: -* Guitar Pro 6-8 -If you want/need support for more file formats to respect the sizing information feel free to [open a discussion](https://github.com/CoderLine/alphaTab/discussions/new?category=ideas) on GitHub. - -## Automatic Mode - -In the automatic mode alphaTab arranges the bars and staves using its internal mechanisms. - -For the `page` layout this means it will scale the bars according to the `stretchForce` and available width. -Wrapping into new systems (rows) will happen when the row is considered "full". - -For the `horizontal` layout the `stretchForce` defines the sizing and no wrapping happens at all. - -## Model Layout mode - -File formats like Guitar Pro embed information about the layout in the file and alphaTab can read and use this information. -When this mode is enabled, alphaTab will also actively use this information and try to respect it. - -alphaTab holds following information in the data model and developers can change those values (e.g. by tapping into the `scoreLoaded`) event. - -**Used when single tracks are rendered:** - -* `score.tracks[index].systemsLayout` - An array of numbers describing how many bars should be placed within each system (row). -* `score.tracks[index].defaultSystemsLayout` - The number of bars to place in a system (row) when no value is defined in the `systemsLayout`. -* `score.tracks[index].staves[index].bars[index].displayScale` - The relative size of this bar in the system it is placed. Note that this is not directly a percentage value. e.g. if there are 3 bars and all define scale 1, they are sized evenly. -* `score.tracks[index].staves[index].bars[index].displayWidth` - The absolute size of this bar when displayed. - -**Used when multiple tracks are rendered:** - -* `score.systemsLayout` - Like the `systemsLayout` on track level. -* `score.defaultSystemsLayout` - Like the `defaultSystemsLayout` on track level. -* `score.masterBars[index].displayScale` - Like the `displayScale` on bar level. -* `score.masterBars[index].displayWidth` - Like the `displayWidth` on bar level. - -### Page Layout - -The page layout uses the `systemsLayout` and `defaultSystemsLayout` to decide how many bars go into a single system (row). -Additionally when sizing the bars within the system the `displayScale` is used. As indicated above, the scale is rather a ratio than a percentage value but percentages work also: - -![Page Layout](/img/reference/property/systems-layout-page-examples.png) - -The page layout does not use `displayWidth`. The use of absolute widths would break the proper alignments needed for this kind of display. - -Also note that the sizing is including any glyphs and notation elements within the bar. e.g. if there are clefs in the bar, they are still "squeezed" into the available size. -It is not the case that the actual notes with their lengths are sized accordingly. This fits the sizing system of Guitar Pro and when files are customized there, -alphaTab will match this layout quite close. - -### Horizontal Layout - -The horizontal layout uses the `displayWidth` to scale the bars to size the bars exactly as specified. This kind of sizing and layout can be useful for usecases like: - -* Comparing files against each other (top/bottom comparison) +The mode used to arrange staves and systems. By default alphaTab uses an own (automatic) mode to arrange and scale the bars when +putting them into staves. This property allows changing this mode to change the music sheet arrangement. + +## Supported File Formats: +* Guitar Pro 6-8 +If you want/need support for more file formats to respect the sizing information feel free to [open a discussion](https://github.com/CoderLine/alphaTab/discussions/new?category=ideas) on GitHub. + +## Automatic Mode + +In the automatic mode alphaTab arranges the bars and staves using its internal mechanisms. + +For the `page` layout this means it will scale the bars according to the `stretchForce` and available width. +Wrapping into new systems (rows) will happen when the row is considered "full". + +For the `horizontal` layout the `stretchForce` defines the sizing and no wrapping happens at all. + +## Model Layout mode + +File formats like Guitar Pro embed information about the layout in the file and alphaTab can read and use this information. +When this mode is enabled, alphaTab will also actively use this information and try to respect it. + +alphaTab holds following information in the data model and developers can change those values (e.g. by tapping into the `scoreLoaded`) event. + +**Used when single tracks are rendered:** + +* `score.tracks[index].systemsLayout` - An array of numbers describing how many bars should be placed within each system (row). +* `score.tracks[index].defaultSystemsLayout` - The number of bars to place in a system (row) when no value is defined in the `systemsLayout`. +* `score.tracks[index].staves[index].bars[index].displayScale` - The relative size of this bar in the system it is placed. Note that this is not directly a percentage value. e.g. if there are 3 bars and all define scale 1, they are sized evenly. +* `score.tracks[index].staves[index].bars[index].displayWidth` - The absolute size of this bar when displayed. + +**Used when multiple tracks are rendered:** + +* `score.systemsLayout` - Like the `systemsLayout` on track level. +* `score.defaultSystemsLayout` - Like the `defaultSystemsLayout` on track level. +* `score.masterBars[index].displayScale` - Like the `displayScale` on bar level. +* `score.masterBars[index].displayWidth` - Like the `displayWidth` on bar level. + +### Page Layout + +The page layout uses the `systemsLayout` and `defaultSystemsLayout` to decide how many bars go into a single system (row). +Additionally when sizing the bars within the system the `displayScale` is used. As indicated above, the scale is rather a ratio than a percentage value but percentages work also: + +![Page Layout](/img/reference/property/systems-layout-page-examples.png) + +The page layout does not use `displayWidth`. The use of absolute widths would break the proper alignments needed for this kind of display. + +Also note that the sizing is including any glyphs and notation elements within the bar. e.g. if there are clefs in the bar, they are still "squeezed" into the available size. +It is not the case that the actual notes with their lengths are sized accordingly. This fits the sizing system of Guitar Pro and when files are customized there, +alphaTab will match this layout quite close. + +### Horizontal Layout + +The horizontal layout uses the `displayWidth` to scale the bars to size the bars exactly as specified. This kind of sizing and layout can be useful for usecases like: + +* Comparing files against each other (top/bottom comparison) * Aligning the playback of multiple files on one screen assuming the same tempo (e.g. one file per track). + +The additional padding to apply between the staves of two separate tracks. + + + diff --git a/docs/reference/settings/exporter/comments.mdx b/docs/reference/settings/exporter/comments.mdx index 059de8d..9a4dcc8 100644 --- a/docs/reference/settings/exporter/comments.mdx +++ b/docs/reference/settings/exporter/comments.mdx @@ -1,5 +1,6 @@ --- title: exporter.comments +sidebar_label: comments sidebar_custom_props: category: Exporter since: 1.7.0 @@ -9,8 +10,6 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description Whether to write extended comments into the exported file (e.g. to in alphaTex to mark where certain metadata or bars starts) - -### Description -How many characters should be indented on formatted outputs. If set to negative values +How many characters should be indented on formatted outputs. If set to negative values formatted outputs are disabled. - -### Description -Enables detecting lyrics from beat texts On various old Guitar Pro 3-5 files tab authors often used the "beat text" feature to add lyrics to the individual tracks. -This was easier and quicker than using the lyrics feature. - -These texts were optimized to align correctly when viewed in Guitar Pro with the default layout but can lead to -disturbed display in alphaTab. When `beatTextAsLyrics` is set to true, alphaTab will try to rather parse beat text -values as lyrics using typical text patterns like dashes, underscores and spaces. - -The lyrics are only detected if not already proper lyrics are applied to the track. - -Enable this option for input files which suffer from this practice. - -> [!NOTE] -> alphaTab tries to relate the texts and chunks to the beats but this is not perfect. -> Errors are likely to happen with such kind of files. - -**Enabled** - -![Enabled](/img/reference/property/beattextaslyrics-enabled.png) - -**Disabled** - +Enables detecting lyrics from beat texts On various old Guitar Pro 3-5 files tab authors often used the "beat text" feature to add lyrics to the individual tracks. +This was easier and quicker than using the lyrics feature. + +These texts were optimized to align correctly when viewed in Guitar Pro with the default layout but can lead to +disturbed display in alphaTab. When `beatTextAsLyrics` is set to true, alphaTab will try to rather parse beat text +values as lyrics using typical text patterns like dashes, underscores and spaces. + +The lyrics are only detected if not already proper lyrics are applied to the track. + +Enable this option for input files which suffer from this practice. + +> [!NOTE] +> alphaTab tries to relate the texts and chunks to the beats but this is not perfect. +> Errors are likely to happen with such kind of files. + +**Enabled** + +![Enabled](/img/reference/property/beattextaslyrics-enabled.png) + +**Disabled** + ![Disabled](/img/reference/property/beattextaslyrics-disabled.png) - -### Description -The text encoding to use when decoding strings. By default strings are interpreted as UTF-8 from the input files. This is sometimes not the case and leads to strong display -of strings in the rendered notation. Via this setting the text encoding for decoding the strings can be changed. The supported -encodings depend on the browser or operating system. This setting is considered for the importers - -* Guitar Pro 7 -* Guitar Pro 6 -* Guitar Pro 3-5 +The text encoding to use when decoding strings. By default strings are interpreted as UTF-8 from the input files. This is sometimes not the case and leads to strong display +of strings in the rendered notation. Via this setting the text encoding for decoding the strings can be changed. The supported +encodings depend on the browser or operating system. This setting is considered for the importers + +* Guitar Pro 7 +* Guitar Pro 6 +* Guitar Pro 3-5 * MusicXML - -### Description If part-groups should be merged into a single track (MusicXML). This setting controls whether multiple `part-group` tags will result into a single track with multiple staves. - -### Description -The transposition pitch offsets for the individual tracks used for rendering only. For some instruments the pitch shown on the standard notation has an additional transposition. One example is the Guitar. -Notes are shown 1 octave higher than they are on the piano. The following image shows a C4 for a piano and a guitar, and a C5 for the piano as comparison: - -![Display Transposition Pitches example](/img/reference/property/displaytranspositionpitches.png) - -The `DisplayTranspositionPitch` setting allows defining an additional pitch offset per track, that is then considered when displaying the music sheet. -This setting does not affect the playback of the instrument in any way. Despite the 2 different standard notations in the above example, they both play the same note height. +The transposition pitch offsets for the individual tracks used for rendering only. For some instruments the pitch shown on the standard notation has an additional transposition. One example is the Guitar. +Notes are shown 1 octave higher than they are on the piano. The following image shows a C4 for a piano and a guitar, and a C5 for the piano as comparison: + +![Display Transposition Pitches example](/img/reference/property/displaytranspositionpitches.png) + +The `DisplayTranspositionPitch` setting allows defining an additional pitch offset per track, that is then considered when displaying the music sheet. +This setting does not affect the playback of the instrument in any way. Despite the 2 different standard notations in the above example, they both play the same note height. The transposition is defined as number of semitones and one value per track of the song can be defined. - -### Description -Whether music notation elements are visible or not. AlphaTab has quite a set of notation elements that are usually shown by default or only shown when using -the `SongBook` notation mode. This setting allows showing/hiding individual notation elements like the -song information or the track names. - -For each element you can configure whether it is visible or not. The setting is a Map/Dictionary where +Whether music notation elements are visible or not. AlphaTab has quite a set of notation elements that are usually shown by default or only shown when using +the `SongBook` notation mode. This setting allows showing/hiding individual notation elements like the +song information or the track names. + +For each element you can configure whether it is visible or not. The setting is a Map/Dictionary where the key is the element to configure and the value is a boolean value whether it should be visible or not. -Internally the setting is a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) where the key must be a enumeration value. -For JSON input the usual enumeration serialization applies where also the names can be used. The names -are case insensitive. - -```js -const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'), { - notation: { - elements: { - scoreTitle: false, - trackNames: false - } - } -}); -api.settings.notation.elements.set(alphaTab.NotationElement.EffectWhammyBar, false); +Internally the setting is a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) where the key must be a NotationElement enumeration value. +For JSON input the usual enumeration serialization applies where also the names can be used. The names +are case insensitive. + +```js +const api = new alphaTab.AlphaTabApi(document.querySelector('#alphaTab'), { + notation: { + elements: { + scoreTitle: false, + trackNames: false + } + } +}); +api.settings.notation.elements.set(alphaTab.NotationElement.EffectWhammyBar, false); ``` -```cs -var settings = new AlphaTab.Settings(); -settings.Notation.Elements[AlphaTab.NotationElement.ScoreTitle] = false; -settings.Notation.Elements[AlphaTab.NotationElement.TrackNames] = false; +```cs +var settings = new AlphaTab.Settings(); +settings.Notation.Elements[AlphaTab.NotationElement.ScoreTitle] = false; +settings.Notation.Elements[AlphaTab.NotationElement.TrackNames] = false; ``` -```kotlin -val settings = AlphaTab.Settings(); -settings.notation.elements[alphaTab.NotationElement.ScoreTitle] = false; -settings.notation.elements[alphaTab.NotationElement.TrackNames] = false; +```kotlin +val settings = AlphaTab.Settings(); +settings.notation.elements[alphaTab.NotationElement.ScoreTitle] = false; +settings.notation.elements[alphaTab.NotationElement.TrackNames] = false; ``` diff --git a/docs/reference/settings/notation/extendbendarrowsontiednotes.mdx b/docs/reference/settings/notation/extendbendarrowsontiednotes.mdx index f50f3dd..62318d1 100644 --- a/docs/reference/settings/notation/extendbendarrowsontiednotes.mdx +++ b/docs/reference/settings/notation/extendbendarrowsontiednotes.mdx @@ -1,5 +1,6 @@ --- title: notation.extendBendArrowsOnTiedNotes +sidebar_label: extendBendArrowsOnTiedNotes sidebar_custom_props: category: Notation since: 0.9.6 @@ -9,12 +10,10 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -If set to true bend arrows expand to the end of the last tied note of the string. Otherwise they end on the next beat. By default the arrows and lines on bend effects are extended to the space of tied notes. This behavior is the Guitar Pro default but some applications and songbooks practice it different. -There the bend only is drawn to the next beat. -| Enabled | Disabled | -|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------| +If set to true bend arrows expand to the end of the last tied note of the string. Otherwise they end on the next beat. By default the arrows and lines on bend effects are extended to the space of tied notes. This behavior is the Guitar Pro default but some applications and songbooks practice it different. +There the bend only is drawn to the next beat. +| Enabled | Disabled | +|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------| | ![Enabled](/img/reference/property/extendbendarrowsontiednotes-enabled.png) | ![Disabled](/img/reference/property/extendbendarrowsontiednotes-disabled.png) | - -### Description -If set to true, line effects like w/bar and let-ring are drawn until the end of the beat instead of the start By default effect annotations that render a line above the staff, stop on the beat. This is the typical display of Guitar Pro. In songbooks and some other tools -these effects are drawn to the end of this beat. -| Enabled | Disabled | -|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------| +If set to true, line effects like w/bar and let-ring are drawn until the end of the beat instead of the start By default effect annotations that render a line above the staff, stop on the beat. This is the typical display of Guitar Pro. In songbooks and some other tools +these effects are drawn to the end of this beat. +| Enabled | Disabled | +|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------| | ![Enabled](/img/reference/property/extendlineeffectstobeatend-enabled.png) | ![Disabled](/img/reference/property/extendlineeffectstobeatend-disabled.png) | - -### Description -The fingering mode to use. AlphaTab supports multiple modes on how to display fingering information in the music sheet. This setting controls how they should be displayed. The default behavior is to show the finger information -directly in the score along the notes. For some use cases of training courses and for beginners this notation might be hard to read. The effect band mode allows to show a single finger information above the staff. - -| Score | Effect Band | -|-------------------------------------------------------------|-------------------------------------------------------------------| +The fingering mode to use. AlphaTab supports multiple modes on how to display fingering information in the music sheet. This setting controls how they should be displayed. The default behavior is to show the finger information +directly in the score along the notes. For some use cases of training courses and for beginners this notation might be hard to read. The effect band mode allows to show a single finger information above the staff. + +| Score | Effect Band | +|-------------------------------------------------------------|-------------------------------------------------------------------| | ![Enabled](/img/reference/property/fingeringmode-score.png) | ![Disabled](/img/reference/property/fingeringmode-effectband.png) | - -### Description -The mode to use for display and play music notation elements. AlphaTab provides 2 main music notation display modes `GuitarPro` and `SongBook`. -As the names indicate they adjust the overall music notation rendering either to be more in line how [Arobas Guitar Pro](https://www.guitar-pro.com) displays it, -or more like the common practice in paper song books practices the display. - -The main differences in the Songbook display mode are: - -1. **Bends** -For bends additional grace beats are introduced. Bends are categorized into gradual and fast bends. - * Gradual bends are indicated by beat text "grad" or "grad.". Bend will sound along the beat duration. - * Fast bends are done right before the next note. If the next note is tied even on-beat of the next note. -2. **Whammy Bars** -Dips are shown as simple annotation over the beats. Whammy Bars are categorized into gradual and fast. - * Gradual whammys are indicated by beat text "grad" or "grad.". Whammys will sound along the beat duration. - * Fast whammys are done right the beat. - -3. **Let Ring** -Tied notes with let ring are not shown in standard notation. Let ring does not cause a longer playback, duration is defined via tied notes. - -4. **Settings** -Following default setting values are applied: -```js -{ - notation: { - smallGraceTabNotes: false, - fingeringMode: alphaTab.FingeringMode.SingleNoteEffectBandm - extendBendArrowsOnTiedNotes: false - }, - elements: { - parenthesisOnTiedBends: false, - tabNotesOnTiedBends: false, - zerosOnDiveWhammys: true - } -} +The mode to use for display and play music notation elements. AlphaTab provides 2 main music notation display modes `GuitarPro` and `SongBook`. +As the names indicate they adjust the overall music notation rendering either to be more in line how [Arobas Guitar Pro](https://www.guitar-pro.com) displays it, +or more like the common practice in paper song books practices the display. + +The main differences in the Songbook display mode are: + +1. **Bends** +For bends additional grace beats are introduced. Bends are categorized into gradual and fast bends. + * Gradual bends are indicated by beat text "grad" or "grad.". Bend will sound along the beat duration. + * Fast bends are done right before the next note. If the next note is tied even on-beat of the next note. +2. **Whammy Bars** +Dips are shown as simple annotation over the beats. Whammy Bars are categorized into gradual and fast. + * Gradual whammys are indicated by beat text "grad" or "grad.". Whammys will sound along the beat duration. + * Fast whammys are done right the beat. + +3. **Let Ring** +Tied notes with let ring are not shown in standard notation. Let ring does not cause a longer playback, duration is defined via tied notes. + +4. **Settings** +Following default setting values are applied: +```js +{ + notation: { + smallGraceTabNotes: false, + fingeringMode: alphaTab.FingeringMode.SingleNoteEffectBandm + extendBendArrowsOnTiedNotes: false + }, + elements: { + parenthesisOnTiedBends: false, + tabNotesOnTiedBends: false, + zerosOnDiveWhammys: true + } +} ``` - -### Description -Controls how high the ryhthm notation is rendered below the tab staff This setting can be used in combination with the setting to control how high the rhythm notation should be rendered below the tab staff. +Controls how high the ryhthm notation is rendered below the tab staff This setting can be used in combination with the rhythmMode setting to control how high the rhythm notation should be rendered below the tab staff. diff --git a/docs/reference/settings/notation/rhythmmode.mdx b/docs/reference/settings/notation/rhythmmode.mdx index 0ef63c0..48b1e20 100644 --- a/docs/reference/settings/notation/rhythmmode.mdx +++ b/docs/reference/settings/notation/rhythmmode.mdx @@ -1,5 +1,6 @@ --- title: notation.rhythmMode +sidebar_label: rhythmMode sidebar_custom_props: category: Notation since: 0.9.6 @@ -9,9 +10,7 @@ import { Tabs, TabItem, CodeBadge, SinceBadge, DynHeading, Link, Signature, Prop - -### Description -Controls how the rhythm notation is rendered for tab staves. This setting enables the display of rhythm notation on tab staffs. [Demo](/docs/showcase/guitar-tabs) +Controls how the rhythm notation is rendered for tab staves. This setting enables the display of rhythm notation on tab staffs. [Demo](/docs/showcase/guitar-tabs) its automatically detected whether rhythm notation should be shown on tabs (based on the visibility of other staves). - -### Description -The height scale factor for slurs Slurs and ties currently calculate their height based on the distance they have from start to end note. Most music notation software do some complex collision detection to avoid a slur to overlap with other elements, alphaTab -only has a simplified version of the slur positioning as of today. This setting allows adjusting the slur height to avoid collisions. The factor defined by this setting, is multiplied with the logarithmic distance between start and end. -| Slur Height Default | Slur Height 14 | -|------------------------------------------------------------------------|--------------------------------------------------------------| +The height scale factor for slurs Slurs and ties currently calculate their height based on the distance they have from start to end note. Most music notation software do some complex collision detection to avoid a slur to overlap with other elements, alphaTab +only has a simplified version of the slur positioning as of today. This setting allows adjusting the slur height to avoid collisions. The factor defined by this setting, is multiplied with the logarithmic distance between start and end. +| Slur Height Default | Slur Height 14 | +|------------------------------------------------------------------------|--------------------------------------------------------------| | ![Slur Height Default](/img/reference/property/slurheight-default.png) | ![Slur Height 14](/img/reference/property/slurheight-14.png) | - -### Description -If set to true the guitar tabs on grace beats are rendered smaller. By default, grace notes are drawn smaller on the guitar tabs than the other numbers. With this setting alphaTab can be configured to show grace tab notes with normal text size. -| Enabled | Disabled | -|--------------------------------------------------------------------|----------------------------------------------------------------------| +If set to true the guitar tabs on grace beats are rendered smaller. By default, grace notes are drawn smaller on the guitar tabs than the other numbers. With this setting alphaTab can be configured to show grace tab notes with normal text size. +| Enabled | Disabled | +|--------------------------------------------------------------------|----------------------------------------------------------------------| | ![Enabled](/img/reference/property/smallgracetabnotes-enabled.png) | ![Disabled](/img/reference/property/smallgracetabnotes-disabled.png) | - -### Description -The transposition pitch offsets for the individual tracks used for rendering and playback. This setting allows transposing of tracks for display and playback. +The transposition pitch offsets for the individual tracks used for rendering and playback. 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. - -### Description -The number of milliseconds the player should buffer. Gets or sets how many milliseconds of audio samples should be buffered in total. - -* Larger buffers cause a delay from when audio settings like volumes will be applied. -* Smaller buffers can cause audio crackling due to constant buffering that is happening. - +The number of milliseconds the player should buffer. Gets or sets how many milliseconds of audio samples should be buffered in total. + +* Larger buffers cause a delay from when audio settings like volumes will be applied. +* Smaller buffers can cause audio crackling due to constant buffering that is happening. + This buffer size can be changed whenever needed. - -### Description -Whether the beat cursor should be animated or just ticking. This setting configures whether the beat cursor is animated smoothly or whether it is ticking from beat to beat. +Whether the beat cursor should be animated or just ticking. This setting configures whether the beat cursor is animated smoothly or whether it is ticking from beat to beat. The animation of the cursor might not be available on all targets so it might not have any effect. - -### Description Whether playback cursors should be displayed. This setting configures whether the playback cursors are shown or not. In case a developer decides to built an own cursor system the default one can be disabled with this setting. Enabling the cursor also requires the player to be active. - -### Description -Whether the notation elements of the currently played beat should be highlighted. This setting configures whether the note elements are highlighted during playback. +Whether the notation elements of the currently played beat should be highlighted. This setting configures whether the note elements are highlighted during playback. The highlighting of elements might not be available on all targets and render engine, so it might not have any effect. - -### Description -Whether the player should be enabled. This setting configures whether the player feature is enabled or not. Depending on the platform enabling the player needs some additional actions of the developer. -For the JavaScript version the [player.soundFont](/docs/reference/settings/player/soundfont) property must be set to the URL of the sound font that should be used or it must be loaded manually via API. -For .net manually the soundfont must be loaded. - +Whether the player should be enabled. This setting configures whether the player feature is enabled or not. Depending on the platform enabling the player needs some additional actions of the developer. +For the JavaScript version the [player.soundFont](/docs/reference/settings/player/soundfont) property must be set to the URL of the sound font that should be used or it must be loaded manually via API. +For .net manually the soundfont must be loaded. + AlphaTab does not ship a default UI for the player. The API must be hooked up to some UI controls to allow the user to interact with the player. - -### Description -Whether the default user interaction behavior should be active or not. This setting configures whether alphaTab provides the default user interaction features like selection of the playback range and "seek on click". +Whether the default user interaction behavior should be active or not. This setting configures whether alphaTab provides the default user interaction features like selection of the playback range and "seek on click". By default users can select the desired playback range with the mouse and also jump to individual beats by click. This behavior can be contolled with this setting. - -### Description -Whether the native browser smooth scroll mechanism should be used over a custom animation. This setting configures whether the [native browser feature](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTo) -for smooth scrolling should be used over a custom animation. -If this setting is enabled, options like will not have an effect anymore. +Whether the native browser smooth scroll mechanism should be used over a custom animation. This setting configures whether the [native browser feature](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTo) +for smooth scrolling should be used over a custom animation. +If this setting is enabled, options like scrollSpeed will not have an effect anymore. - -### Description The mode used for playing audio samples Controls how alphaTab will play the audio samples in the browser. - -### Description -Whether the player should be enabled and which mode it should use. This setting configures whether the player feature is enabled or not. Depending on the platform enabling the player needs some additional actions of the developer. - -**Synthesizer** - -If the synthesizer is used (via or ) a sound font is needed so that the midi synthesizer can produce the audio samples. - -For the JavaScript version the [player.soundFont](/docs/reference/settings/player/soundfont) property must be set to the URL of the sound font that should be used or it must be loaded manually via API. -For .net manually the soundfont must be loaded. - -**Backing Track** - -For a built-in backing track of the input file no additional data needs to be loaded (assuming everything is filled via the input file). -Otherwise the `score.backingTrack` needs to be filled before loading and the related sync points need to be configured. - -**External Media** - -For synchronizing alphaTab with an external media no data needs to be loaded into alphaTab. The configured sync points on the MasterBars are used -as reference to synchronize the external media with the internal time axis. Then the related APIs on the AlphaTabApi object need to be used -to update the playback state and exterrnal audio position during playback. - -**User Interface** - +Whether the player should be enabled and which mode it should use. This setting configures whether the player feature is enabled or not. Depending on the platform enabling the player needs some additional actions of the developer. + +**Synthesizer** + +If the synthesizer is used (via EnabledAutomatic or EnabledSynthesizer ) a sound font is needed so that the midi synthesizer can produce the audio samples. + +For the JavaScript version the [player.soundFont](/docs/reference/settings/player/soundfont) property must be set to the URL of the sound font that should be used or it must be loaded manually via API. +For .net manually the soundfont must be loaded. + +**Backing Track** + +For a built-in backing track of the input file no additional data needs to be loaded (assuming everything is filled via the input file). +Otherwise the `score.backingTrack` needs to be filled before loading and the related sync points need to be configured. + +**External Media** + +For synchronizing alphaTab with an external media no data needs to be loaded into alphaTab. The configured sync points on the MasterBars are used +as reference to synchronize the external media with the internal time axis. Then the related APIs on the AlphaTabApi object need to be used +to update the playback state and exterrnal audio position during playback. + +**User Interface** + AlphaTab does not ship a default UI for the player. The API must be hooked up to some UI controls to allow the user to interact with the player. - -### Description Whether the triplet feel should be played or only displayed. If this setting is enabled alphaTab will play the triplet feels accordingly, if it is disabled the triplet feel is only displayed but not played. - -### Description -The element to apply the scrolling on. When the player is active, it by default automatically scrolls the browser window to the currently played bar. This setting -defines which elements should be scrolled to bring the played bar into the view port. By default scrolling happens on the `html,body` +The element to apply the scrolling on. When the player is active, it by default automatically scrolls the browser window to the currently played bar. This setting +defines which elements should be scrolled to bring the played bar into the view port. By default scrolling happens on the `html,body` selector. - -### Description The mode how to scroll. This setting controls how alphaTab behaves for scrolling. - -### Description -The X-offset to add when scrolling. When alphaTab does an auto-scrolling to the displayed bar, it will try to align the view port to the displayed bar. If due to -some layout specifics or for aesthetics a small padding is needed, this setting allows an additional X-offset that is added to the +The X-offset to add when scrolling. When alphaTab does an auto-scrolling to the displayed bar, it will try to align the view port to the displayed bar. If due to +some layout specifics or for aesthetics a small padding is needed, this setting allows an additional X-offset that is added to the scroll position. - -### Description -The Y-offset to add when scrolling. When alphaTab does an auto-scrolling to the displayed bar, it will try to align the view port to the displayed bar. If due to -some layout specifics or for aesthetics a small padding is needed, this setting allows an additional Y-offset that is added to the +The Y-offset to add when scrolling. When alphaTab does an auto-scrolling to the displayed bar, it will try to align the view port to the displayed bar. If due to +some layout specifics or for aesthetics a small padding is needed, this setting allows an additional Y-offset that is added to the scroll position. - -### Description -How fast the scrolling to the new position should happen. If possible from the platform, alphaTab will try to do a smooth scrolling to the played bar. -This setting defines the speed of scrolling in milliseconds. -Note that must be set to `false` for this to have an effect. +How fast the scrolling to the new position should happen. If possible from the platform, alphaTab will try to do a smooth scrolling to the played bar. +This setting defines the speed of scrolling in milliseconds. +Note that nativeBrowserSmoothScroll must be set to `false` for this to have an effect. - -### Description -The slide settings allow control how the different slide types are generated for audio. AlphaTab supports various types of slides which can be grouped into 3 types: - -* Shift Slides -* Legato Slides - - -* Slide into from below -* Slide into from above -* Slide out to below -* Slide out to above - - -* Pick Slide out to above -* Pick Slide out to below - -For the first 2 groups the audio generation can be adapted. For the pick slide the audio generation cannot be adapted -as there is no mechanism yet in alphaTab to play pick slides to make them sound real. - -For the first group only the duration or start point of the slide can be configured while for the second group +The slide settings allow control how the different slide types are generated for audio. AlphaTab supports various types of slides which can be grouped into 3 types: + +* Shift Slides +* Legato Slides + + +* Slide into from below +* Slide into from above +* Slide out to below +* Slide out to above + + +* Pick Slide out to above +* Pick Slide out to below + +For the first 2 groups the audio generation can be adapted. For the pick slide the audio generation cannot be adapted +as there is no mechanism yet in alphaTab to play pick slides to make them sound real. + +For the first group only the duration or start point of the slide can be configured while for the second group the duration/start-point and the pitch offset can be configured. - -### Description -The bend duration in milliseconds for songbook bends. If the display mode `songbook` is enabled, this has an effect on the way bends are played. For songbook bends the bend is done very quickly at the end or start of the beat. -This setting defines the play duration for those bends in milliseconds. This duration is in milliseconds unlike some other settings which are in midi ticks. The reason is that on songbook bends, +The bend duration in milliseconds for songbook bends. If the display mode `songbook` is enabled, this has an effect on the way bends are played. For songbook bends the bend is done very quickly at the end or start of the beat. +This setting defines the play duration for those bends in milliseconds. This duration is in milliseconds unlike some other settings which are in midi ticks. The reason is that on songbook bends, the bends should always be played in the same speed, regardless of the song tempo. Midi ticks are tempo dependent. - -### Description -The duration of whammy dips in milliseconds for songbook whammys. If the display mode `songbook` is enabled, this has an effect on the way whammy dips are played. For songbook dips the whammy is pressed very quickly at the start of the beat. -This setting defines the play duration for those whammy bars in milliseconds. This duration is in milliseconds unlike some other settings which are in midi ticks. The reason is that on songbook dips, +The duration of whammy dips in milliseconds for songbook whammys. If the display mode `songbook` is enabled, this has an effect on the way whammy dips are played. For songbook dips the whammy is pressed very quickly at the start of the beat. +This setting defines the play duration for those whammy bars in milliseconds. This duration is in milliseconds unlike some other settings which are in midi ticks. The reason is that on songbook dips, the whammy should always be pressed in the same speed, regardless of the song tempo. Midi ticks are tempo dependent. - -### Description The sound font file to load for the player. When the player is enabled the soundfont from this URL will be loaded automatically after the player is ready. - -### Description -The Vibrato settings allow control how the different vibrato types are generated for audio. AlphaTab supports 4 types of vibratos, for each vibrato the amplitude and the wavelength can be configured. The amplitude controls how many semitones -the vibrato changes the pitch up and down while playback. The wavelength controls how many midi ticks it will take to complete one up and down vibrato. -The 4 vibrato types are: - -1. Beat Slight - A fast vibrato on the whole beat. This vibrato is usually done with the whammy bar. -2. Beat Wide - A slow vibrato on the whole beat. This vibrato is usually done with the whammy bar. -3. Note Slight - A fast vibrato on a single note. This vibrato is usually done with the finger on the fretboard. +The Vibrato settings allow control how the different vibrato types are generated for audio. AlphaTab supports 4 types of vibratos, for each vibrato the amplitude and the wavelength can be configured. The amplitude controls how many semitones +the vibrato changes the pitch up and down while playback. The wavelength controls how many midi ticks it will take to complete one up and down vibrato. +The 4 vibrato types are: + +1. Beat Slight - A fast vibrato on the whole beat. This vibrato is usually done with the whammy bar. +2. Beat Wide - A slow vibrato on the whole beat. This vibrato is usually done with the whammy bar. +3. Note Slight - A fast vibrato on a single note. This vibrato is usually done with the finger on the fretboard. 4. Note Wide - A slow vibrato on a single note. This vibrato is usually done with the finger on the fretboard. {` +\\extendBarLines +\\track "Piano1" + \\staff {score} + \\instrument piano + C4 D4 E4 F4 | \\barlineright dashed C4 D4 E4 F4 | C4 D4 E4 F4 | + \\staff {score} + \\clef f4 C3 D3 E3 F3 | \\barlineright dashed +\\instrument flute + C4 D4 E4 F4 +\\track "Flute 2" + \\staff { score } +\\instrument flute + \\clef f4 C3 D3 E3 F3 +\\track "Guitar 1" + \\staff { score tabs } + 0.3.4 2.3.4 5.3.4 7.3.4 +`} + +#### render: multi-system slurs +https://github.com/CoderLine/alphaTab/pull/2425 + +Previously alphaTab only rendered slurs on single-system breaks. If a slur spans multiple systems +this caused an incorrect display. With this improvement we can now have slurs spanning many systems +until the end bar is reached. + +The alignment of these slurs has been improved to resemble the height at the starting system. + +{` +\\track {defaultsystemslayout 3} +C4 {slur s1} .1 | r | r | +r | r | r | +r | C4 {slur s1} | r +`} + +#### render: improved note head alignment and displacement. +https://github.com/CoderLine/alphaTab/pull/2426 + +https://github.com/CoderLine/alphaTab/pull/2430 + +With this change we now align note heads according to more common practices. + +The first change is to align the primary note heads on the same axis. Basically: on an upwards stem the left note heads, and on a downwards stem the right noteheads are now aligned. +Displaced note-heads are shifted to the other side of the stem. + +With this improvement as a base, we now also merge or further shift note-heads when multiple voices are contained in a bar. +This way the readability is improved and unnecessary white-space is avoided. + +{` +\\voice +E5*5 +\\voice +C5 D5 E5 F5 G5`} + +#### render: in-score chord diagrams +https://github.com/CoderLine/alphaTab/pull/2435 + +Often requested but never shipped. Now they are available: chord diagrams inside the music sheet. + +Previously alphaTab could only show the used chord as diagrams on top of the score. +With this change chord diagrams can be shown inside the music sheet above the staff. + +{` +\\chordDiagramsInScore +\\chord ("E" 0 0 1 2 2 0) {showDiagram false} +(0.1 0.2 1.3 2.4 2.5 0.6){ch "E"} +`} + +#### render: numbered notation ties and dash placement +https://github.com/CoderLine/alphaTab/pull/2438 + +alphaTab 1.7 had some incorrect display of numbered notation. Following improvements were added in this release: + +* The beats are now correctly showing the respective duration with dashes and additional number glyphs as expected. +* The dots and overflow calculations have been reworked to avoid overlaps +* The "beam" drawing logic has been updated to be closer to the common logic. +* We do not render beams for grace notes anymore. +* key signature has been moved to an own effect band. + +{` +\staff {score numbered} +\hidedynamics + +C5.1 | C4 {tu 3} * 3 +\staff +C4.4 *4 +`} + +#### render: hide empty staves +https://github.com/CoderLine/alphaTab/pull/2443 + +With this feature we add an option to hide staves if they are empty. This feature mainly targets +the multi-track display and multi-staff instruments. If the option is configured, any staves +without content will be hidden. + +At this point alphaTab will not hide whole systems to avoid side-effects during playback and the related cursor placement. +If alphaTab detects tha all systems are empty, it will force the first one to be visible. + +{` +\\hideEmptyStaves +\\defaultSystemsLayout 3 +\\multiTrackTrackNamePolicy allSystems +\\track "T1" +C4.4 *4 | r.1 | r.1 | + r.1 | r.1 | r.1 | + r.1 | r.1 | r.1 | + r.1 | r.1 | r.1 | + r.1 | C4 | + +\\track "T2" +\\clef C3 + r.1 | r.1 | r.1 | + r.1 | r.1 | r.1 | + r.1 | c4 | r.1 | + r.1 | r.1 | r.1 | + r.1 | C4 | +`} + + +#### render: parchment layout +https://github.com/CoderLine/alphaTab/pull/2459 + +The parchment layout is is a variation of the currently available `page` layout. THe special thing about this layout is that the +configured systems layout is always active. For the `page` layout a separate option was required to enable the usage of the systems layout +which configures the number of bars shown in every system. + +The parchment layout is typically more optimized for printing and fixed layouts where the exact positioning and sizing of elements is important. + +{` +\\track {systemslayout (2 3 2)} + \\scale 2 C4 * 4 | + \\scale 1 C4 * 4 | + \\scale 2 C4 * 4 | + \\scale 1 C4 * 4 | + \\scale 2 C4 * 4 | + \\scale 0.5 C4 * 4 | + \\scale 1 C4 * 4 | +`} + +#### notation: buzzroll tremolos +https://github.com/CoderLine/alphaTab/pull/2476 + +With this change we now support buzroll tremolos. It can be separately configured if these tremolos should be played like classical +ones. + +{` +:4 +C4 {tp 1} | +C4 {tp 2} | +C4 {tp 3} | +C4 {tp (3 buzzRoll)} | +`} + +#### render: advanced font configurations and lyric paddings +https://github.com/CoderLine/alphaTab/pull/2481 + +This improvement changes extends how fonts can be configured in alphaTab. +Previously the `settings.display.resources` had specific properties for individual items lacking flexibility for a range of elements. + +With this change devs can now configure fonts for a wide range of individual `NotationElement.*` values. The old general `effectFont` was +deprecated and fonts can now be configured individually as desired. + +This feature started with a request to customize the display of lyrics. To support this request further, the padding between individual +lyric lines can now be configured via `settings.display.lyricLinesPaddingBetween` + +TODO sample + +#### render: configure display of bar numbers +https://github.com/CoderLine/alphaTab/pull/2482 + +Before this release alphaTab was always rendering bar numbers on all bars. Devs could trick the display by setting the bar number color +but this was not really a sustainable approach. + +With this feature it can now be configured whether to show bar numbers on + +1. all bars +2. no bars +3. the first bars of every system + +We now read the respective information from supported input formats (Guitar Pro, MusicXML, alphaTex) to respect the intentions of the transcriber. + +{` +\\defaultBarNumberDisplay firstOfSystem +C4.1 | C4.1 | C4.1 | +C4.1 | C4.1 | C4.1 +`} + + +{` +\\defaultBarNumberDisplay hide +C4.1 | \\barNumberDisplay allBars C4.1 | C4.1 | +C4.1 | C4.1 | C4.1 +`} + + +#### notation: custom beaming rules +https://github.com/CoderLine/alphaTab/pull/2489 + +alphaTab 1.8 ships significant improvements around the beaming of notes. +Previously alphaTab had only 2 rules on how notes were beamed. + +With alphaTab 1.8 not only we have **27** optimized breaming rules for a range of common time signatures. +Users can now fully custoimze how notes should be beamed. + +We read the information contained in Guitar Pro files and alphaTex provides new metadata tags for this feature. +In worst case devs can opt to set the rules after loading any custom file. + +{` +\\ts (4 4) +\\beaming (8 2 2 2 2) + C4.8 * 8 | +\\beaming (8 2 4 2) + C4.8 * 8 | +\\ts (4 4) +\\beaming (16 4 4 8) + C4.16 * 8 + C4.16 * 8 +`} + +### Player + +#### player: grace beats on song start +https://github.com/CoderLine/alphaTab/pull/2415 + +Grace Beats take a special role in music notation and have a fairly unique behavior regarding display and playback. + +These beats do not have their own "playback time", they steal their duration from the previous or next beat, shortening it in the process. + +In Guitar Pro terminology there are `on-beat` grace notes and `before-beat` grace notes stealing the duration from the next or previous beat respectively. +This becomes a problem when we place a `before-beat` at the start of the song because there is no "previous beat" from which we can steal the duration. + +This was a problem for alphaTab as the time of this beat was suddenly negative resulting in incorrect playback and cursor placement. Normally the author of the music sheet would need to +rewrite the notes to have some sort of beat to steal the duration from (e.g. via pick-up/anacrusis bar or changing to an on-beat grace note). +This individualization is not always possible if the input file is consumed from an external source. + +We now internally handle this negative underlow and ensure the playback and display works as a user would expect it. + +TOOD samples + +#### player: smooth cursor and scrolling +https://github.com/CoderLine/alphaTab/pull/2447 + +This feature adds a brand new scroll mode allowing a continuous smooth scrolling experience. +The previously available modes were scrolling when the played bar changed and the related positioning condition was met (e.g. the bar was out-of-screen). + +For horizontal layouts this allows a steady-cursor at a fixed position. +For vertical layouts it allows a more relaxed scrolling without main jumps making it easier to follow the playback. + +On top of that devs can now implement a custom scrolling logic. We extracted the current scrolling logic into +dedicated components and allow devs to set their own implementations. + +This way new extended scrolling systems can be built. + +TODO sample + +### Guitar Pro extensions + +### exporter: improved RSE compatibility +https://github.com/CoderLine/alphaTab/pull/2456 +https://github.com/CoderLine/alphaTab/pull/2477 + +Thanks [@L-Sun](https://github.com/CoderLine/alphaTab/pull/2456) for your contributions around this topic. + +With these improvements alphaTab does now write extended RSE information into the exported Guitar Pro files. +This way the playback mode in Guitar Pro can be changed to RSE resulting in proper playback. + +RSE is quite a complex feature of Guitar Pro allowing advanced effect and soundbank configurations. alphaTab tries +to write at least the minimum amount of information to achieve correct playback. + +TODO sample + +### importer: detect bass clef (Guitar Pro 3-5) +https://github.com/CoderLine/alphaTab/pull/2483 + +Older Guitar Pro files did not always contain the exact information on what clef should be shown on the staves. +While some information can be contained, it was not fully working as expected and for older formats always a treble clef was shown. + +We now follow the Guitar Pro 5 behavior of switching to the a bass clef based on the configured string tuning. + +TODO sample + +### alphaTex Extensions + +#### alphaTex: bar-wise voices +https://github.com/CoderLine/alphaTab/pull/2429 + +While writing various test-cases for multi-voice music sheets I realized that writing +the notation voice-by-voice does not feel very natural. + +By default in alphaTex, to write multiple voices, you first write the whole notation for the first voiec, +then you start a new voice with `\voice` and begin again writing the second voice at bar 1. + +With this new mode, we stay in the metal model of writing notation "bar-by-bar". The `\voice` tag starts a new +voice on the current bar until we reach the end of the bar. Thanks to this you can only add a second voice to the +bars which actually have a second voice and keep the other bars simple as single voice bars. + +alphaTab takes care of the internal consolidation of voices. + +TODO sample. + +### Improvements & Bugfixes + +#### integration: Selection API +https://github.com/CoderLine/alphaTab/pull/2418 + +This change extends the public APIs around the interactive selection of the playback range. +Previously devs needed to rely on some internal behaviors to extend the alphaTab selection logic +with custom parts. This made it close to impossible to cleanly implement extensions like custom +selection handles. + +With these changes developers can now subscribe to events during the interactive selection of a user +and create new UI elements as needed (e.g. to create extended selection handles). + +Additionally we ensure now to snap the selection start to the beginning of the bar if the selection starts +on the first beat. + +TODO sample + +#### alphaTex: Fixed diagnostics in Monaco integration +https://github.com/CoderLine/alphaTab/pull/2413 + +Some last minute changes in the 1.7.0 release caused a problem that the Monaco Editor integration +didn't correctly display diagnostics. Due to both pull&pull diagnostics being used, all diagnostics were +listed twice. + +#### alphaTex: Missing metadata tags in LSP completion +https://github.com/CoderLine/alphaTab/pull/2413 + +Some metadata tags were not included in the list for code completions. Any staff-level metadata tags were missing +in the code completions. + +Now they are included as expected. + +#### playground: Impovements in the development playground +https://github.com/CoderLine/alphaTab/pull/2410 + +The development playground was improved with some more convenience features like: + +1. When importing any file into the alphaTex editor, we use the new exporter to fill the code editor with the alphaTex code for further editing. +2. Drag and drop of files now works on the whole page +3. alphaTab is now exposed on the `window` object for easy fiddling in the browser dev tools. + +#### render: Effect bands merged into main renderers +https://github.com/CoderLine/alphaTab/pull/2414 + +This is mainly a preparation for future improvements but still worth mentioning in this release. +Until this release effects&annotations like vibratos, dynamics, lyrics etc. were rendered in own +`EffectBarRenderers`. + +Internally this means there were own visual "staves" for the various effects and these staves were tricky to manage. + +With this change we merged these effects into the main renderers bringing following improvements: + +1. We layed the foundation to eventually align effects more efficiently with the notes contained in the bars allowing a more dense layout. + Currently there can be quite a lot of white-space (especially in the horizontal layout). +2. When the main staves (standard notation, tabs, slash notation and numbered notation) are shown/hidden we tell the next main staff to show the effect instead. + Thanks to this all relevant effects are now shown for notes. +3. Internally there is less complexity and overhead resulting in a slightly better performance. + +As part of this various alignment issues have been fixed and we improved the general behavior of reserving paddings for overlaps. + +#### alphaTex: load alphaTex from the `textContent` of DOM elements. +https://github.com/CoderLine/alphaTab/pull/2417 +https://github.com/CoderLine/alphaTab/commit/962b45b98b751003dcee47f5c3b557350e44ee13 + +alphaTab previously used the `.innerHTML` property of DOM elements to load the initial alphaTex code to render. +Due to this HTML entities were escaped and a text like `alpha & tab` would result in `alpha & tab`. + +With the change to `textContent` this problem does not exist anymore and whitespace is still preserved for parsing mitigating +expected side-effects. + +#### rendering: improved beaming helpers +https://github.com/CoderLine/alphaTab/pull/2427 + +The beaming helpers are responsible for grouping beats which can be beamed together and take care of various +calculations around this. + +Historically a lot of logic around the positioning of beams and related elements (tuplets, flags etc) was scattered +across differetn places. With this improvement we have now a proper centralized handling of these aspects allowing easier +adaptions and extensions for future features. + +Along the way this resulted in a range of improvements for the rendered notation: + +* reserved overflows and paddings are now more precise causing less unneeded whitespace and (hopefully) no cropping. + +TODO sample + +#### bundlers: warn about missing plugin usage +https://github.com/CoderLine/alphaTab/pull/2436 + +We now detect during runtime if alphaTab was bundled via WebPack or Vite but our bundler plugins were not used. +This mitigates problems when devs forget to setup the bundlers correctly. + +Unless alphaTab logs are disabled in the browser, the browser console will print a warning if the plugins need to be activated. + +#### rendering: always apply `systemLabelPaddingLeft` +https://github.com/CoderLine/alphaTab/pull/2448 + +alphaTab only applied the padding `systemLabelPaddingLeft` if the tracks had a label. Now this padding is always applied ensuring a +consistent display regardless of track names being set. + +TODO sample + +#### web: print dialog +https://github.com/CoderLine/alphaTab/pull/2480 + +When we introduced the SMuFL font customization the print dialog got broken. The fonts were not registered in the +print dialog and therefore no symbols were shown. This problem is now fixed. + +TODO sample + +#### audio: handle invalid BPMs +https://github.com/CoderLine/alphaTab/pull/2484 + +There were some edge-cases where invalid files could lead to a hang inside alphaTab. If BPMs were set to a value <1 (e.g. 0.111), +alphaTab cropped it to 0. A BPM=0 then caused a range of internal problems in the player. + +alphaTab now forces the BPM to 1 inside the player to avoid any problems. + +TODO sample + +#### rendering: prevent wobbly beam rendering +https://github.com/CoderLine/alphaTab/pull/2494 + +alphaTab tried to handle certain subpixel related problems by rounding coordinates. This had the negative effect of +beams not aligning to a clean slope but they appeared "wobbly" when spanning multiple beats. + +We fixed the rendering of these beams aiming for a clean display of slopes and avoiding sub-pixel related artifacts. + +On standard-DPI monitors there might still be slight artifacts due to subpixel-rendering and the related anti-aliasing. + +TODO sample + +#### rendering: avoid flickering and wrong notation display on layout changes +https://github.com/CoderLine/alphaTab/pull/2495 + +When switching between layouts, alphaTab tried to keep the existing notation displayed. +This optimization was mainly in place for dynamic resizing. When switching between layouts or loading new files, +this could lead to wrong elements being displayed on screen temporarily until they were re-rendered using the new information. + +alphaTab now tries to detect whether the current viewport elements can be reused and clears the content if required. + +Devs can supply new `renderingHints` in a range of API methods for scenarios where the data model is dynamically changing but generally +the displayed notation stays similar. + +e.g. when providing live editors a clearing of the viewport would have negative flickering effects when clearing all rendered notation. + +TODO sample \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index caca3b4..2d6adcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "alphatab-website", "version": "0.0.0", "dependencies": { - "@coderline/alphatab": "^1.7.1", + "@coderline/alphatab": "^1.8.0-alpha.1671", "@docusaurus/core": "^3.9.2", "@docusaurus/preset-classic": "^3.9.2", "@docusaurus/theme-mermaid": "^3.9.2", @@ -242,6 +242,7 @@ "version": "5.42.0", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.42.0.tgz", "integrity": "sha512-NZR7yyHj2WzK6D5X8gn+/KOxPdzYEXOqVdSaK/biU8QfYUpUuEA0sCWg/XlO05tPVEcJelF/oLrrNY3UjRbOww==", + "peer": true, "dependencies": { "@algolia/client-common": "5.42.0", "@algolia/requester-browser-xhr": "5.42.0", @@ -377,6 +378,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1887,6 +1889,7 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "license": "MIT", + "peer": true, "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -1992,9 +1995,10 @@ "license": "Apache-2.0" }, "node_modules/@coderline/alphatab": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@coderline/alphatab/-/alphatab-1.7.1.tgz", - "integrity": "sha512-Rsh+HEWJxcn2ahMR/5bzPkmeadL3ZSXFboZ46t1Y71tdsysJqlrrKtjx/yaOhULDWL4q1kq0EVcbqlYngcFRyQ==", + "version": "1.8.0-alpha.1671", + "resolved": "https://registry.npmjs.org/@coderline/alphatab/-/alphatab-1.8.0-alpha.1671.tgz", + "integrity": "sha512-UPsO4XCCW+B55EgyLv6vyR7/M+P7MOZlP/fvlUmqmdJv/86ahYdnVhGrcDfeNhTw3qHXCvGD2afRXuv1UR76fg==", + "license": "MPL-2.0", "engines": { "node": ">=6.0.0" } @@ -2013,6 +2017,16 @@ "alphatab-language-server": "dist/server.mjs" } }, + "node_modules/@coderline/alphatab-language-server/node_modules/@coderline/alphatab": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@coderline/alphatab/-/alphatab-1.7.1.tgz", + "integrity": "sha512-Rsh+HEWJxcn2ahMR/5bzPkmeadL3ZSXFboZ46t1Y71tdsysJqlrrKtjx/yaOhULDWL4q1kq0EVcbqlYngcFRyQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@coderline/alphatab-webpack": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@coderline/alphatab-webpack/-/alphatab-webpack-1.7.1.tgz", @@ -2136,6 +2150,7 @@ "url": "https://opencollective.com/csstools" } ], + "peer": true, "engines": { "node": ">=18" }, @@ -2157,6 +2172,7 @@ "url": "https://opencollective.com/csstools" } ], + "peer": true, "engines": { "node": ">=18" } @@ -2261,6 +2277,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2666,6 +2683,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3383,6 +3401,7 @@ "version": "3.9.2", "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz", "integrity": "sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==", + "peer": true, "dependencies": { "@docusaurus/babel": "3.9.2", "@docusaurus/bundler": "3.9.2", @@ -3558,6 +3577,7 @@ "version": "3.9.2", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", + "peer": true, "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/logger": "3.9.2", @@ -4778,6 +4798,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -5415,6 +5436,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -5981,6 +6003,7 @@ "version": "19.0.10", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -6704,6 +6727,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6795,6 +6819,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -6837,6 +6862,7 @@ "version": "5.42.0", "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.42.0.tgz", "integrity": "sha512-X5+PtWc9EJIPafT/cj8ZG+6IU3cjRRnlHGtqMHK/9gsiupQbAyYlH5y7qt/FtsAhfX5AICHffZy69ZAsVrxWkQ==", + "peer": true, "dependencies": { "@algolia/abtesting": "1.8.0", "@algolia/client-abtesting": "5.42.0", @@ -7305,6 +7331,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -7582,6 +7609,7 @@ "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -8261,6 +8289,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8563,6 +8592,7 @@ "version": "3.31.1", "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.1.tgz", "integrity": "sha512-Hx5Mtb1+hnmAKaZZ/7zL1Y5HTFYOjdDswZy/jD+1WINRU8KVi1B7+vlHdsTwY+VCFucTreoyu1RDzQJ9u0d2Hw==", + "peer": true, "engines": { "node": ">=0.10" } @@ -8937,6 +8967,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "peer": true, "engines": { "node": ">=12" } @@ -10095,6 +10126,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14603,6 +14635,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -15114,6 +15147,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -15969,6 +16003,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16737,6 +16772,7 @@ "version": "19.0.0", "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -16745,6 +16781,7 @@ "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "peer": true, "dependencies": { "scheduler": "^0.25.0" }, @@ -16795,6 +16832,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "peer": true, "dependencies": { "@types/react": "*" }, @@ -16821,6 +16859,7 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -17550,6 +17589,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.1.tgz", "integrity": "sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag==", "dev": true, + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -18653,7 +18693,8 @@ "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "peer": true }, "node_modules/tsx": { "version": "4.19.3", @@ -18729,6 +18770,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "devOptional": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19075,6 +19117,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -19294,6 +19337,7 @@ "version": "5.102.1", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -19864,6 +19908,7 @@ "version": "4.1.12", "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 919cd68..7a9199f 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "generate-alphatabdoc-empty": "tsx scripts/generate-alphatabdoc.mts --empty" }, "dependencies": { - "@coderline/alphatab": "^1.7.1", + "@coderline/alphatab": "^1.8.0-alpha.1671", "@docusaurus/core": "^3.9.2", "@docusaurus/preset-classic": "^3.9.2", "@docusaurus/theme-mermaid": "^3.9.2", diff --git a/scripts/generate-alphatex.mts b/scripts/generate-alphatex.mts index 7f91f2a..6f44bc6 100644 --- a/scripts/generate-alphatex.mts +++ b/scripts/generate-alphatex.mts @@ -42,7 +42,7 @@ async function generatePropertiesDocs(file: string, props: Map = { + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, + member: TMember +} + export async function generateApiDocs(context: GenerateContext) { const basePath = path.join(repositoryRoot, "docs", "reference", "api"); await fs.promises.mkdir(basePath, { recursive: true }); - const properties: ( - | ts.PropertyDeclaration + const properties: Member[] = []; - const events: ( - | ts.PropertyDeclaration + const events: Member[] = []; - const methods: (ts.MethodDeclaration | ts.MethodSignature)[] = []; + const methods: Member[] = []; const members: Map = new Map(); collectMembers(context, members, context.flatExports.get( @@ -47,18 +50,26 @@ export async function generateApiDocs(context: GenerateContext) { const categories = new ReferenceTableData(); - for (const m of Array.from(members.values())) { if (isEvent(context, m)) { - events.push(m as (typeof events)[0]); + events.push({ + parent: m.parent as ts.ClassDeclaration | ts.InterfaceDeclaration, + member: m as ts.PropertyDeclaration + }); } else if ( ts.isPropertyDeclaration(m) || ts.isPropertySignature(m) || ts.isGetAccessorDeclaration(m) ) { - properties.push(m); + properties.push({ + parent: m.parent as ts.ClassDeclaration | ts.InterfaceDeclaration, + member: m as ts.PropertyDeclaration + }); } else if (ts.isMethodDeclaration(m) || ts.isMethodSignature(m)) { - methods.push(m); + methods.push({ + parent: m.parent as ts.ClassDeclaration | ts.InterfaceDeclaration, + member: m as ts.MethodDeclaration + }); } } @@ -80,41 +91,40 @@ export async function generateApiDocs(context: GenerateContext) { async function writeProperties( context: GenerateContext, basePath: string, - properties: ( - | ts.PropertyDeclaration + properties: Member[], referenceTable: ReferenceTableData ) { for (const member of properties) { - await writePropertyPage(context, basePath, member, referenceTable); + await writePropertyPage(context, basePath, member.parent, member.member, referenceTable); } } async function writeMethods( context: GenerateContext, basePath: string, - methods: (ts.MethodDeclaration | ts.MethodSignature)[], + methods: Member[], referenceTable: ReferenceTableData ) { for (const member of methods) { - await writeMethodPage(context, basePath, member, referenceTable); + await writeMethodPage(context, basePath, member.parent, member.member, referenceTable); } } async function writeEvents( context: GenerateContext, basePath: string, - events: ( - | ts.PropertyDeclaration + events: Member< + ts.PropertyDeclaration | ts.PropertySignature | ts.GetAccessorDeclaration - )[], + >[], referenceTable: ReferenceTableData ) { for (const member of events) { - await writeEventPage(context, basePath, member, referenceTable); + await writeEventPage(context, basePath, member.parent, member.member, referenceTable); } } @@ -171,6 +181,7 @@ async function writeFrontMatter( async function writePropertyPage( context: GenerateContext, basePath: string, + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, member: | ts.PropertyDeclaration | ts.PropertySignature @@ -194,12 +205,13 @@ async function writePropertyPage( await fileStream.write("\n"); - await writePropertyDetails(context, fileStream, member); + await writePropertyDetails(context, fileStream, parent, member); } async function writeEventPage( context: GenerateContext, basePath: string, + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, member: | ts.PropertyDeclaration | ts.PropertySignature @@ -212,12 +224,13 @@ async function writeEventPage( await using fileStream = await openFileStream(filePath); await writeFrontMatter(context, fileStream, memberName, member, "event", referenceTable); - await writeEventDetails(context, fileStream, member); + await writeEventDetails(context, fileStream, parent, member); } async function writeMethodPage( context: GenerateContext, basePath: string, + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, member: ts.MethodDeclaration | ts.MethodSignature, referenceTable: ReferenceTableData ) { @@ -228,5 +241,5 @@ async function writeMethodPage( await writeFrontMatter(context, fileStream, memberName, member, "method", referenceTable); - await writeMethodDetails(context, fileStream, member); + await writeMethodDetails(context, fileStream, parent, member); } diff --git a/scripts/generate-common.mts b/scripts/generate-common.mts index 3aa6891..95cf1c9 100644 --- a/scripts/generate-common.mts +++ b/scripts/generate-common.mts @@ -585,14 +585,11 @@ function getDeclarationReferenceUrl( case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.PropertySignature: let page = (element as ts.ClassElement).name!.getText().toLowerCase(); - if (page === "index") { - page = "index_"; - } return ( getDeclarationReferenceUrl( context, element.parent as ts.ClassDeclaration | ts.InterfaceDeclaration, - ) + '/' + page + ) + '/#' + page ); case ts.SyntaxKind.EnumMember: return ( @@ -600,7 +597,7 @@ function getDeclarationReferenceUrl( context, element.parent as ts.EnumDeclaration ) + - "#" + + "/#" + (element as ts.EnumMember).name!.getText().toLowerCase() ); case ts.SyntaxKind.TypeParameter: @@ -745,18 +742,22 @@ function isInternal(context: GenerateContext, node: ts.Node) { export async function writeEventDetails( context: GenerateContext, fileStream: FileStream, + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, member: | ts.PropertySignature | ts.PropertyDeclaration - | ts.GetAccessorDeclaration + | ts.GetAccessorDeclaration, + referenceDoc: boolean = false ) { - await writeCommonDescription(context, fileStream, member); + await writeCommonDescription(context, fileStream, parent, member, referenceDoc); await writeEventSignatures(context, fileStream, member); - await writeManualDocs(fileStream, member); + if (!referenceDoc) { + await writeManualDocs(fileStream, member); - await writeExamples(fileStream, context, member); + await writeExamples(fileStream, context, member); + } } export async function writeEventSignatures( @@ -773,27 +774,32 @@ export async function writeEventSignatures( export async function writeMethodDetails( context: GenerateContext, fileStream: FileStream, - member: ts.MethodDeclaration | ts.MethodSignature + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, + member: ts.MethodDeclaration | ts.MethodSignature, + referenceDoc: boolean = false ) { - await writeCommonDescription(context, fileStream, member); + await writeCommonDescription(context, fileStream, parent, member, referenceDoc); await writeMethodSignatures(context, fileStream, member); await writeMethodParameters(context, fileStream, member); - await writeMethodReturn(context, fileStream, member); + await writeMethodReturn(context, fileStream, member, referenceDoc ? 4 : 3); - await writeManualDocs(fileStream, member); + if (!referenceDoc) { + await writeManualDocs(fileStream, member); - await writeExamples(fileStream, context, member); + await writeExamples(fileStream, context, member); + } } -export async function writeMethodReturn( +async function writeMethodReturn( context: GenerateContext, fileStream: FileStream, - m: ts.MethodDeclaration | ts.MethodSignature + m: ts.MethodDeclaration | ts.MethodSignature, + level: number ) { const returnsDoc = getJsDocTagText(context, m, "returns"); if (returnsDoc) { - await fileStream.write(`### Returns \n`); + await fileStream.write(`${'#'.repeat(level)} Returns \n`); await fileStream.write(`${returnsDoc} \n\n`); } } @@ -1030,13 +1036,46 @@ export async function writeCommonImports(fileStream: FileStream, additionals: st await fileStream.writeLine(); } +function getInheritenceInfo( + context: GenerateContext, + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, + member: ts.ClassElement | ts.TypeElement +) { + let info = ""; + // inheritence info + if (member.parent !== parent) { + info += " (Inherited from "; + const builder = new TypeReferencedCodeBuilder(context); + builder.declaration( + member.parent as ts.ClassDeclaration | ts.InterfaceDeclaration + ); + + let name = (member.parent as ts.NamedDeclaration).name!.getText(); + if (context.nameToExportName.has(name)) { + name = context.nameToExportName.get(name)!; + } + + info += builder.toMdx("js", "inline"); + + info += ")"; + } + return info; +} + + async function writeCommonDescription( context: GenerateContext, fileStream: FileStream, - member: ts.TypeElement | ts.ClassElement + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, + member: ts.TypeElement | ts.ClassElement, + referenceDoc: boolean ) { - await fileStream.write(`\n### Description\n`); - await fileStream.write(`${getFullDescription(context, member)}\n\n`); + await fileStream.write(`${getFullDescription(context, member)}`); + if (referenceDoc) { + await fileStream.write(`${getInheritenceInfo(context, parent, member)}`); + } + + await fileStream.write(`\n\n`); } export async function writeManualDocs( @@ -1065,18 +1104,21 @@ export async function writeManualDocs( export async function writePropertyDetails( context: GenerateContext, fileStream: FileStream, + parent: ts.ClassDeclaration | ts.InterfaceDeclaration, member: | ts.PropertySignature | ts.PropertyDeclaration - | ts.GetAccessorDeclaration + | ts.GetAccessorDeclaration, + referenceDoc: boolean = false ) { - await writeCommonDescription(context, fileStream, member); + await writeCommonDescription(context, fileStream, parent, member, referenceDoc); await writePropertySignatures(context, fileStream, member); - await writeManualDocs(fileStream, member); - - await writeExamples(fileStream, context, member); + if (!referenceDoc) { + await writeManualDocs(fileStream, member); + await writeExamples(fileStream, context, member); + } } export const cconsole = { @@ -1362,6 +1404,7 @@ type TypeReferencedCodeLanguage = "js" | "c#" | "kotlin"; export class TypeReferencedCodeBuilder { private chunks: TypeReferencedCodeToken[] = []; + public links = true; public constructor(private context: GenerateContext) { } @@ -1388,6 +1431,10 @@ export class TypeReferencedCodeBuilder { public declaration(t: ts.NamedDeclaration, linkText?: string) { linkText ??= t.name?.getText() ?? "UnknownReference"; + if (!this.links) { + return this.identifier(linkText); + } + const referenceUrl = getDeclarationReferenceUrl(this.context, t as any); if (referenceUrl) { this.chunks.push({ @@ -1440,6 +1487,32 @@ export class TypeReferencedCodeBuilder { this.chunks = []; } + public toPlain(language: TypeReferencedCodeLanguage) { + let plain = ''; + + const translated = this.translateChunks(this.chunks, language); + for (const chunk of translated) { + switch (chunk.kind) { + case "identifier": + case "token": + case "keyword": + case "whitespace": + plain += escapeHtmlEntities(chunk.content.toString()); + break; + + // case "type": // rewritten during translateChunks + // break; + case "link": + const link = chunk.content as TypeReferencedCodeLink; + plain += escapeHtmlEntities(link.linkText); + break; + } + } + + + return plain; + } + public toJSON(language: TypeReferencedCodeLanguage) { const translated = this.translateChunks(this.chunks, language); @@ -1468,10 +1541,11 @@ export class TypeReferencedCodeBuilder { public toMdx( language: TypeReferencedCodeLanguage, - style: "block" | "inline" + style: "block" | "inline", + basicName: string = '' ) { let code = `'; + code += '={' + this.toJSON(language) + '}>' + this.toPlain(language) + ' '; return code; } diff --git a/scripts/generate-settings.mts b/scripts/generate-settings.mts index 042f240..00edbff 100644 --- a/scripts/generate-settings.mts +++ b/scripts/generate-settings.mts @@ -81,6 +81,7 @@ export async function generateSettings(context: GenerateContext) { `title: ${page.title}\n` ); + await fileStream.write(`sidebar_label: ${member.name.getText()}\n`); await fileStream.write(`sidebar_custom_props:\n`); if (page.javaScriptOnly) { @@ -109,7 +110,7 @@ export async function generateSettings(context: GenerateContext) { await fileStream.write(`\n`); - await writePropertyDetails(context, fileStream, member); + await writePropertyDetails(context, fileStream, subSettingType, member); } } } diff --git a/scripts/generate-typedocs.mts b/scripts/generate-typedocs.mts index d79f492..e1ef609 100644 --- a/scripts/generate-typedocs.mts +++ b/scripts/generate-typedocs.mts @@ -1,23 +1,22 @@ -import path from "path"; import fs from "fs"; -import { - GenerateContext, - getTypeWithNullableInfo, - repositoryRoot, -} from "./typeschema.mjs"; +import path from "path"; +import ts from "typescript"; import { collectMembers, getFullDescription, getJsDocTagText, - getSummary, isEvent, + TypeReferencedCodeBuilder, writeCommonImports, writeEventDetails, writeMethodDetails, - writePropertyDetails, - TypeReferencedCodeBuilder, + writePropertyDetails } from "./generate-common.mjs"; -import ts from "typescript"; +import { + GenerateContext, + getTypeWithNullableInfo, + repositoryRoot, +} from "./typeschema.mjs"; import { FileStream, openFileStream } from "./util.mjs"; export async function generateTypeDocs(context: GenerateContext) { @@ -48,9 +47,6 @@ export async function generateTypeDocs(context: GenerateContext) { fileStream.suspend = context.emptyFiles; await writeCommonImports(fileStream); - await fileStream.write( - `\nDescription\n\n` - ); await fileStream.write(`${getFullDescription(context, exportedType)}\n\n`); if ( @@ -170,18 +166,16 @@ export async function generateTypeDocs(context: GenerateContext) { await writeProperties( context, fileStream, - basePath, exportedType, properties ); await writeMethods( context, fileStream, - basePath, exportedType, methods ); - await writeEvents(context, fileStream, basePath, exportedType, events); + await writeEvents(context, fileStream, exportedType, events); } } else if (ts.isEnumDeclaration(exportedType)) { await writeEnumMembers(context, fileStream, exportedType); @@ -192,7 +186,6 @@ export async function generateTypeDocs(context: GenerateContext) { async function writeProperties( context: GenerateContext, fileStream: FileStream, - basePath: string, parent: ts.ClassDeclaration | ts.InterfaceDeclaration, properties: ( | ts.PropertyDeclaration @@ -205,70 +198,25 @@ async function writeProperties( } await fileStream.write( - `\nProperties\n\n` - ); - - await fileStream.write( - `\n` + `\n## Properties\n\n` ); - await fileStream.write(` \n`); for (const member of properties) { - await fileStream.write(` \n`); - const referenceBuilder = new TypeReferencedCodeBuilder(context); + referenceBuilder.links = false; referenceBuilder.declaration(member); - await fileStream.write( - ` \n` - ); - - referenceBuilder.reset(); - referenceBuilder.type( - getTypeWithNullableInfo( - context, - member.type, - true, - !!member.questionToken - ) - ); - - await fileStream.writeLine( - ` {props.detailed && ()}` - ); - let defaultValue = getJsDocTagText(context, member, "defaultValue"); - if (!defaultValue) { - defaultValue = "(no default)"; - } - await fileStream.writeLine( - ` {props.detailed && }` - ); - - let description = - getSummary(context, member, true, true) + - getInheritenceInfo(context, parent, member); - - await fileStream.write(` \n`); - - await fileStream.write(` \n`); - await writePropertyPage(context, basePath, member); + await writePropertyDetails(context, fileStream, parent, member, true); } - await fileStream.write(` \n`); - await fileStream.write(`
${referenceBuilder.toMdx("js", "inline")}${referenceBuilder.toMdx("js", "inline")}{${JSON.stringify(defaultValue)}}\n`); await fileStream.write( - `${description - .split("\n") - .map((l) => ` ${l}`) - .join("\n")}\n` + `\n### ${referenceBuilder.toMdx("js", "inline")}\n\n` ); - await fileStream.write(`
\n`); } async function writeMethods( context: GenerateContext, fileStream: FileStream, - basePath: string, parent: ts.ClassDeclaration | ts.InterfaceDeclaration, methods: (ts.MethodDeclaration | ts.MethodSignature)[] ) { @@ -277,50 +225,25 @@ async function writeMethods( } await fileStream.write( - `\nMethods\n\n` - ); - - await fileStream.write( - `\n` + `\n## Methods \n\n` ); - await fileStream.write(` \n`); for (const member of methods) { - await fileStream.write(` \n`); - const parameters = member.parameters - .map((p) => p.type!.getText()) - .join(", "); - await fileStream.write( - ` \n` - ); + const referenceBuilder = new TypeReferencedCodeBuilder(context); + referenceBuilder.declaration(member); - let description = - getSummary(context, member, true, true) + - getInheritenceInfo(context, parent, member); - await fileStream.write(` \n`); - await fileStream.write(` \n`); - - await writeMethodPage(context, basePath, member); + await writeMethodDetails(context, fileStream, parent, member, true); } - await fileStream.write(` \n`); - await fileStream.write(`
[\`${member.name.getText()}(${parameters})\`](./${member.name - .getText() - .toLowerCase()}.mdx)\n`); await fileStream.write( - `${description - .split("\n") - .map((l) => ` ${l}`) - .join("\n")}\n` + `\n### ${referenceBuilder.toMdx("js", "inline")}\n\n` ); - await fileStream.write(`
\n`); } async function writeEvents( context: GenerateContext, fileStream: FileStream, - basePath: string, parent: ts.ClassDeclaration | ts.InterfaceDeclaration, events: ( | ts.PropertyDeclaration @@ -333,41 +256,21 @@ async function writeEvents( } await fileStream.write( - `\nEvents\n\n` - ); - - await fileStream.write( - `\n` + `\n## Events\n\n` ); - await fileStream.write(` \n`); for (const member of events) { - await fileStream.write(` \n`); - await fileStream.write( - ` \n` - ); + const referenceBuilder = new TypeReferencedCodeBuilder(context); + referenceBuilder.declaration(member); - let description = - getSummary(context, member, true, true) + - getInheritenceInfo(context, parent, member); - await fileStream.write(` \n`); + await fileStream.write(`${getFullDescription(context, member)}\n\n`); - await fileStream.write(` \n`); - - await writeEventPage(context, basePath, member); + await writeEventDetails(context, fileStream, parent, member, true); } - await fileStream.write(` \n`); - await fileStream.write(`
[\`${member.name.getText()}\`](./${member.name - .getText() - .toLowerCase()}.mdx)\n`); await fileStream.write( - `${description - .split("\n") - .map((l) => ` ${l}`) - .join("\n")}\n` + `\n### ${referenceBuilder.toMdx("js", "inline")}\n\n` ); - await fileStream.write(`
\n`); } async function writeEnumMembers( @@ -376,7 +279,7 @@ async function writeEnumMembers( exportedType: ts.EnumDeclaration ) { await fileStream.write( - `\nEnum Members\n\n` + `\n### Enum Members\n\n` ); await fileStream.write( @@ -444,82 +347,3 @@ async function writeFrontMatter( await fileStream.write(`\n`); } } - -async function writePropertyPage( - context: GenerateContext, - basePath: string, - member: - | ts.PropertyDeclaration - | ts.PropertySignature - | ts.GetAccessorDeclaration -) { - let memberName = member.name!.getText(); - let fileName = memberName.toLowerCase(); - if (memberName === "index") { - fileName = "index_"; - } - - const filePath = path.join(basePath, fileName + ".mdx"); - - await using fileStream = await openFileStream(filePath); - - await writeFrontMatter(context, fileStream, memberName, member, "property"); - await writePropertyDetails(context, fileStream, member); -} - -async function writeEventPage( - context: GenerateContext, - basePath: string, - member: - | ts.PropertyDeclaration - | ts.PropertySignature - | ts.GetAccessorDeclaration -) { - const memberName = member.name!.getText(); - const filePath = path.join(basePath, memberName.toLocaleLowerCase() + ".mdx"); - - await using fileStream = await openFileStream(filePath); - - await writeFrontMatter(context, fileStream, memberName, member, "event"); - await writeEventDetails(context, fileStream, member); -} - -async function writeMethodPage( - context: GenerateContext, - basePath: string, - member: ts.MethodDeclaration | ts.MethodSignature -) { - const memberName = member.name!.getText(); - const filePath = path.join(basePath, memberName.toLocaleLowerCase() + ".mdx"); - - await using fileStream = await openFileStream(filePath); - - await writeFrontMatter(context, fileStream, memberName, member, "method"); - await writeMethodDetails(context, fileStream, member); -} - -function getInheritenceInfo( - context: GenerateContext, - parent: ts.ClassDeclaration | ts.InterfaceDeclaration, - member: ts.ClassElement | ts.TypeElement -) { - let info = ""; - // inheritence info - if (member.parent !== parent) { - info += " (Inherited from "; - const builder = new TypeReferencedCodeBuilder(context); - builder.declaration( - member.parent as ts.ClassDeclaration | ts.InterfaceDeclaration - ); - - let name = (member.parent as ts.NamedDeclaration).name!.getText(); - if (context.nameToExportName.has(name)) { - name = context.nameToExportName.get(name)!; - } - - info += builder.toMdx("js", "inline"); - - info += ")"; - } - return info; -} diff --git a/sidebars.ts b/sidebars.ts index f896dea..6c58392 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -62,7 +62,7 @@ const sidebars: SidebarsConfig = { id: "reference/settings", }, className: "reference-item", - collapsible: false, + collapsible: true, collapsed: true, items: [ { @@ -79,7 +79,7 @@ const sidebars: SidebarsConfig = { id: "reference/api", }, className: "reference-item", - collapsible: false, + collapsible: true, collapsed: true, items: [ { @@ -144,15 +144,15 @@ const sidebars: SidebarsConfig = { alphaTex: [ { type: 'doc', - id: "alphatex/introduction" + id: "alphatex/introduction" }, { type: 'doc', - id: "alphatex/syntax" + id: "alphatex/syntax" }, { type: 'doc', - id: "alphatex/document-structure" + id: "alphatex/document-structure" }, { type: 'category', @@ -167,18 +167,18 @@ const sidebars: SidebarsConfig = { "alphatex/beat-properties", "alphatex/note-properties", ] - }, + }, { type: 'doc', - id: "alphatex/importer" + id: "alphatex/importer" }, { type: 'doc', - id: "alphatex/lsp" + id: "alphatex/lsp" }, { type: 'doc', - id: "alphatex/monaco" + id: "alphatex/monaco" } ], }, diff --git a/src/components/MarkdownString/index.tsx b/src/components/MarkdownString/index.tsx deleted file mode 100644 index 69818eb..0000000 --- a/src/components/MarkdownString/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -// MdxPreview -import React, { useEffect, useState } from "react"; -import { evaluate } from "@mdx-js/mdx"; -import * as runtime from "react/jsx-runtime"; - -export type MarkdownStringProps = { content: string }; -export const MarkdownString: React.FC = ({ content }: MarkdownStringProps) => { - const exports = useMDX(content); - const Content = exports.default; - return ; -}; - -function useMDX(content: string) { - const [exports, setExports] = useState({ default: runtime.Fragment }); - - useEffect(() => { - evaluate(content, { ...(runtime as any) }).then((exports) => - setExports(exports as any) - ); - }, [content]); - - return exports; -} diff --git a/src/components/Signature/index.tsx b/src/components/Signature/index.tsx index 4cc33ef..ff3bbfd 100644 --- a/src/components/Signature/index.tsx +++ b/src/components/Signature/index.tsx @@ -2,6 +2,7 @@ import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; import { FC } from "react"; import Link from "@docusaurus/Link"; +import { useDoc } from "@docusaurus/plugin-content-docs/lib/client/doc.js"; export type SignatureToken = [string, string] | [string, string, string]; @@ -83,14 +84,16 @@ export const Signature: FC = ({ style, js, csharp, kotlin }) => return (); } else { - return ({ label: i.label, value: i.value }))}> - {items.map(i => ( - - - - ))} - + return
+ ({ label: i.label, value: i.value }))}> + {items.map(i => ( + + + + ))} + +
} }; diff --git a/src/css/custom.scss b/src/css/custom.scss index 09cfafc..b06cdb5 100644 --- a/src/css/custom.scss +++ b/src/css/custom.scss @@ -87,10 +87,6 @@ img.thumbnail { position: relative; } -li.reference-item ul { - display: none !important; -} - li.types-item .menu__list-item-collapsible { flex-wrap: no-wrap; } @@ -272,9 +268,32 @@ body.playground { } } } + } +} + +.signature-tabs { + margin-top: calc(var(--ifm-leading) * -1); + &>.tabs-container { + margin-bottom: 0; + &>.margin-top--md { + margin-top: 0 !important; + } } -} + .tabs { + justify-content: flex-end; + } + .tabs__item { + padding: 0.1rem 0.2rem; + border-radius: 0; + font-weight: normal; + font-size: 80%; + } + + .codeBlockContainer .codeBlockLines { + padding: 0.25rem; + } +} \ No newline at end of file