Giter Club home page Giter Club logo

xetune's People

Contributors

j5v avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

xetune's Issues

Audition selected notes with timbre

As a user, I want to hear selected notes played with a voiced timbre.

Sine tones can quickly become tiring because they provide fewer 'partials' clues, and need to be played with more energy to be heard and decomposed by the ear. They also don't reflect what is likely to be played by the production instrument.

See also #29 for advantages of auditioning within XeTune.

Before implementing, consider whether it's sufficiently easy to import a XeTune tuning into whatever DAW/sequencer/instrument the user is familiar with, and play there. For a unique production tone or expression, this might be the route a user takes.

We want to strike a good balance between convenience and complexity. It should be easy to select from a few relevant timbres, and significantly less work than configuring a synth to play the tuned notes. We should stop well short of writing a production synth.

Touchscreen usability: hover text or status info

Mouseover title text, while helpful to mouse users, cannot be viewed on a touch device.

As a mobile user, I want to see more precise details for analysis cells, where details are only displayed as mouseover text.

Refactor UX selection and tools for tunings

Currently, the tool matrix of icons is duplicated for each tuning row. The user selects an icon directly, to operate on the tuning row.

Consider a 'tuning selection' UI, along with a global toolbar that operates on selected tunings.

This would simplify the display, but it would increase the number of gestures required for most operations.

Notes

  1. Evaluate what actions need to remain on a tuning row, and whether the space saving and simplification is worth the UI refactor.
  2. Create the paradigm of 'tuning selection', and 'tuning focus' for accessibility. Actions: Select all, Toggle selection of current, and Select none.
  3. For accessibility, add keyboard shortcuts for actions, and for toolbar/tunings focus, because focus navigation is difficult when actions (a toolbar) are separated from the navigable target objects.
  4. With 'tunings selection', keyboard shortcuts for actions would be unambiguous, as the action buttons are present only once in the UI, and use tuning selection as context.
  5. Check feasibility of the toolbar design, and the experience of a fragmented UI.

Audition selected notes

As a user, I want to hear selected notes, as a sequence or as a chord.

MVP: sine tones.

Auditioning within XeTune has advantages:

  • One press to audition a selected chord
  • No need to physically play a chord on an instrument/controller.
  • No need to figure out where a tuning's notes will appear on the played controller keyboard, and no need to configure a keyboard mapping to match the tuning.

Reorder tuning strips

As a user, I want to reorder the tuning strips.

Consider:

  • Drag and drop
  • Up/down buttons (good only for a few moves; tiresome for more)

Drag and drop is not accessible for keyboard-only users, so if drag and drop is done, it would be helpful to also provide keyboard-focusable button on each tuning strip that activates a move operation controlled with cursor keys, finalized by Enter/Space keys, and aborted by the Escape key.

New ratio tuining options: offset and offset per log-unit

For the ratio-based tuning options, I want controlled imperfections that give specific effects.

This enables octave stretching, shimmer, phase effects, and degrees of dissonance that might make tunings more interesting.

Parameters

  • Add x Hz [and compensate reference frequency]
  • Add x Hz per n/m

Persist config more often

Currently, the configuration does not persist in localStorage unless the user selects Configure from the toolbar, then Save (without necessarily making changes to the configuration).

As a user, I want configuration to persist with major changes of UI state or data, particularly when:

  • I add, remove, or duplicate a tuning.
  • I change any note data.
  • I close the app.
  • I change any configurable profiles (future feature).

Perhaps selection of notes can be exempt, or on a debounced timer, so that selections and limits save infrequently.

Support more import/export formats

Which formats should XeTune support?

Some future-gazing questions that might help answer that:

  1. Would users benefit from interoperability with other apps, and preserve metadata that the .scl format loses?
  2. Do we need to store XeTune tunings as a portable file, and is a proprietary format required for that?
  3. Do other formats store essential data that we cannot infer otherwise?
  4. Do we need to persist as a file, data that adds value to tunings, notes, analysis, or configuration profiles. For example, user-provided annotations, generators of tunings, or filtered views?

My instinct is to await user needs (features) that require file persistence, before reaching for proprietary or compatible formats.

Separate UI state from config

Problem

config should contain only configuration state. It currently contains: configuration state, current project data (tunings and their notes), UI state (selections).

Approach

This is a 'could-do' issue that helps code comply with the principle of separating concerns. It carries regression risk if implemented wholly. It can be ignored for the time being, but the problem might become significant when we provide explicit interfaces for configuration options.

While it's beneficial to save UI state that the user is invested in, it should really be separated out into UI state, and perhaps persisted as a UI state object, so that invested selections are restored over sessions.

Some UI state, like tunings[].notes[].selected would need to be separated out, and use serializable references. Most of the code addresses tunings and notes by .id, but look out for synchronization issues when arrays of objects are mutated.

Drag to select multiple notes

As a user, I want to select a range of notes in a tuning, by dragging a box over them.

MVP brief

  1. Indicate a drag rectangle or shaded selection region as the mouse is dragged over the tuning. It must be visible for any density of notes.
  2. Optionally, highlight included notes during drag.
  3. After releasing the left mouse button (or primary touch), the select any notes whose centres fall within the selection region, and deselect any notes that fall outside the region.

Extended brief

Move to another issue if these are not completed.

  1. Use key modifier Ctrl, to not modify notes outside the selection, and to toggle the first note dragged over, and set all notes within the selection region consistently with that note.

Tuning override of global 'note 0' reference

As a user, I work with multiple tunings with different reference frequencies, and want this reflected in analysis, and displayed above each overridden tuning row at the appropriate point on the tuning line. I need an optional reference frequency in each tuning, to override the global reference, and want to edit this in Tuning properties.

Follows from #23.
'Could-do' because fewer users need this.

Clarify limit implied by label of generated ratio-based tuning

XeTune auto-generates tunings, but the label for ratio-based limits is misleading.

e.g. 9-limit is usually interpreted as a prime limit, but currently, XeTune generates only integer-limit ratio tunings.

Brief

  1. Change the label for integer-limit ratio tunings, to indicate the integer limit, e.g. 9i-limit.

Stub: Subjective analysis of selected note intervals

Some long-term aims for this project, when it is mature enough:

  1. To analyse an interval or chord, to then describe how it might sound subjectively.
  2. To analyse a sequence of chords or notes, to then describe how they might sound subjectively in context.

Expand these into issues when ready.

Analysis of one ED tuning

As a user, I want an analysis of all currently-visible intervals of one selected ED tuning, displayed in a new Tunings tab.

Hints

We currently have a hidden tab, and logic to branch out to analysis modes for:

  • Analysis of an ED tuning, as a single row or column. <-- this issue
  • Tuning 1 vs Tuning 1 analysis in a grid, for a non-ED tuning.
  • Tuning 1 vs Tuning 2 analysis in a grid.

This issue implements content for the function analysisEDTuningIntervalsHTML(), which currently holds placeholder text.

Proposed content

MVP: reuse the analysis cell from analysisNoteIntervalsHTML(), but presented as a single column or row of intervals (rather than a grid).

Better: Implement a table with all the details exposed.

Tuning generation: more algorithms

Consider which generation algorithms to add to XeTune. For example:

  1. Equal division between existing notes.
  2. Create a new tuning from selected notes with offset (+Hz) or scaling (octaves or cents).
  3. Multi-tier tunings that cannot be composed using smaller steps in XeTune.

Research new tuning series.

UI for config: global 'note 0' reference

As a user, I want to specify the Global reference frequency for note 0 of all tunings. After specifying the reference frequency, I want note values to reflect this change, and to be able to re-edit the Global reference frequency in the same way I specified it.

This is a 'should-do' issue, because performance scenarios are often not based on 440Hz, and analysis should reflect the performance scenario.

Approach

An explicit UI for configuration of the base frequency, e.g. toolbar icon -> dialog.
Currently, we define this as an offset from 440Hz (A)

const config = {
  ...
  noteRefHz: 440 * (Math.pow(2, -9/12)), // C, around 261 Hz // TODO: split to be configurable
  ...
}

It might be helpful to provide a friendly interface to specify a reference frequency (Hz) and offsets in other units.

The UI currently shows the global reference frequency config.noteRefHz at the appropriate point above the tuning rows. So many (nearly all) UI elements depend on config.noteRefHz, so a call to renderApp() will refresh these*.

*An event-subscription pattern would also work, but that would be significant effort and change, hard to maintain, and likely less efficient in practice.

Background

In production workflows, a tuning configuration doesn't specify the base frequency of a tuning (Hz of note 0). Rather that's the responsibility of the virtual instrument, tuning controller, or controller that uses a .kbm (keyboard map file, where reference frequency is embedded).

However, a reference frequency is useful:

  • if XeTune develops audio previews.
  • if absolute frequency is important to the analysis experience, e.g. to quantify beat frequency for two playing notes.

The caveat is that XeTune is not responsible for transmitting the reference frequency, because conventional workflows assign this responsibility elsewhere, and the tuning file (in the case of .scl) cannot ordinarily carry this data. Users need to synchronize the two independent sources of reference frequency.

User-accessible reset

As a user, if I find the app won't refresh or won't start because the configuration causes an irrecoverable error, then provide a button that resets the configuration to default.

Suggestion

Provide a reset button in the initial HTML, which is replaced by the render.
This will provide safety for errors that occur until the composed HTML is committed to the DOM, which is the last step in most cases.

Calculate the importance of ratios

The named ratios already have a .level property in ref.noteNamesHarmonic[], which indicates their importance in the UI (low values for .level imply important notes). More important ratios are displayed as heavier lines in the tuning row, and their shorthand labels display above the note button.

However, this applies only for ratios below integer limit 11.

Do we need to calculate the importance of other ratios, or ED generated notes that are near important ratios?

If yes, do we need to dynamically change the thresholds for visual effects? We currently have configurable thresholds for:

config: {
    ...
    noteShowSubtleLinesBelowLevel: 5,
    noteShowLabelsBelowLevel: 3,
    nearEnoughCents: 8, // for letter labels of notes
    ...
}

Tuning: Add note

As a user, I want to add a note to a tuning, from the Add note button on a tuning row.

MVP: An Add note dialog with a free text field that allows entry of ratio, cents, or Hz. Provide help text to explain this in the dialog.

When the user submits the Add note dialog, populate all the remaining properties of the note. This might best be combined with a refactor of the other code that populates note properties, e.g. the expandTuning functions.

Use useful limits in scale generation and analysis

Currently, scale generation and interval analysis use a set of ratios that were generated to integer limits, e.g. a maximum value for n and m, for ratio = n / m.

Incorporate different types of limits:

  1. Integer limit (implemented already)
  2. Odd limit (not implemented).
  3. Prime limit (partly implemented).

ratiosToPrimeLimit() already generates ratios to prime limit, but it's not exposed to the UI. It generates too many results, and needs limiting further.

Proposal

(possibly over-engineered!)

Allow the user to select options of Integer limit, Odd limit, and Prime limit. At least one is required.

Parameters

Integer limit takes an integer parameter

Odd limit takes an integer parameter

Prime limit takes:

  • an integer Prime limit parameter.
  • For each of the prime numbers up to limit, an integer parameter for the Maximum exponent. The Maximum exponent may be negative or positive or zero.

Profiles

Allow the user to create profiles that store the above parameters. Suggest this UI is opened from the main toolbar.

Provide some default profiles:

  • Integer limit: 99
  • Odd limit: (2-3 useful profiles)
  • Prime limit: (8-ish useful profiles)

Allow choice of these profiles in:

  • New tuning [button -> dialog] > Limited ratios [dropdown option].
  • Any analysis tab that uses ratio limits, e.g. Intervals.

Notes

  1. The generation of ratios is a relatively expensive processing operation, and should be cached where possible: certainly for analysis, which is triggered whenever the Intervals tab is open and a note is selected or unselected.
  2. Where possible, label a generated scale according to the type of limit used, by concatenating instances of , e.g. 7p999i-limit, for a 'prime 7-limit' further limited by an 'integer limit of 999'.

Omnisearch

Would an omnisearch improve usability?
Omnisearch is a search box in the toolbar, which searches everything in the app. Selecting a suggestion in a pop-up list triggers an action.

Some examples, as a user:

  1. I can search for known named tunings that are not in the current project, and when I select a result, the tuning displays as a new tuning.
  2. I can enter a formatted name for a generated tuning (like 31-EDO), and when I select a result, the tuning displays as a new tuning.
  3. I can enter the name of an interval. e.g. perfect fifth, P5, or G6. Two actions display for each matching interval name: Select notes, and Create notes. I can select these actions to execute.
  4. I can enter an action name, e.g. delete, and resulting actions like Remove selected notes or Remove selected tunings display. I can select these actions to execute.

Grid analysis two tunings

As a user, I want an analysis of all currently-visible intervals of two selected tunings, displayed in a new Tunings tab.

Hints

We currently have a hidden tab, and logic to branch out to analysis modes for:

  • Analysis of an ED tuning, as a single row or column.
  • Tuning 1 vs Tuning 1 analysis in a grid, for a non-ED tuning.
  • Tuning 1 vs Tuning 2 analysis in a grid. <-- this issue

This issue implements content for the function analysisTwoTuningsTableHTML(), which currently holds placeholder text.

Proposed content

Reuse the layout and cell content from analysisNoteIntervalsHTML(). 'Refectoring for reuse' might be beneficial.

Note properties (analysis tab) - edit

As a user, I want to edit details for the last-touched note in a tuning strip, in a Note properties tab in the analysis section of the UI.

Follows #11

The note object contains many properties that must be kept consistent. For example, if the user edits the Frequency (Hz) of a note defined as a ratio, then several properties will need fixing up.

Notes

  1. This solution might be usefully combined with a refactor of other code that populates all note properties from minimal data.

Note properties (analysis tab) - view

As a user, I want to view details for the last-touched note in a tuning strip, in a Note properties tab in the analysis section of the UI.

This is the first step; the second step allows robust editing of the note data.

Tuning scale: uncrowd overlapping notes

As a user, I don't want to see overlapping notes on a tuning scale.

Note: I'm calling this a bug, because currently, important visual data is obscured. Enhancement with an improved positioning algorithm will fix it.

Proposed (simple) solution

Where rendering a note in the default location would overlap previous notes, place the note lower in the row band. For each note attempt to place at the top, and repeatedly try lower until there is space.

This requires expanding the row band, and consequently the total size of the tunings SVG.

Stretch goal

Analyse whether other patterns and vertical spacings may result in better distributions or keep row expansion to a minimum. If note importance is implemented, see whether that can be used to ensure the important notes are placed at the top of the tuning band.

Configuration not reloaded, for persistence

Enable loading of the configuration.

Consider also providing a 'reset' that is accessible in the UI, so that users are not left with an unusable app if there's an error loading the configuration.

Generated ED tunings don't cover required ranges

Fix: For ED or generated repeating tunings, dynamically infer notes outside the explicitly defined range 0 .. Repeat ratio. Don't overwrite user-customized notes. Indicate inferred notes in the UI.

Background

Most tunings are cyclic, defined explicitly over a Repeat ratio. Any notes outside the explicit range should be inferred for display and analysis.

Currently for ED tunings, we generate notes in the range -1 octaves .. +3 octaves, and export only the range -1 to , inclusive. While this works for most scenarios, it can be tricky to infer the provenance of individual notes (especially after editing), and we currently don't properly cover the display range for all sensible Repeat ratio values.

We already set tunings[].notes[].isDefined, but need some analysis about the instantiation of implied 'ghost' notes for on-demand drawing and UI interactions, and whether they should persist in the tunings[].notes[] array - and if so, do we use tunings[].notes[].isDefined to distinguish explicit from implicit notes?

Suggestion

Whenever view parameters change (e.g. zoom bounds on the tuning rows, or analysis), expand/re-generate notes, setting .isDefined = false. This needs a function to solve boundary frequency or count limits for scale generation.

Grid analysis of a non-ED tuning against itself

As a user, I want an analysis of all currently-visible intervals of one selected non-ED tuning, displayed in a new Tunings tab.

Hints

We currently have a hidden tab, and logic to branch out to analysis modes for:

  • Analysis of an ED tuning, as a single row or column.
  • Tuning 1 vs Tuning 1 analysis in a grid, for a non-ED tuning. <-- this issue
  • Tuning 1 vs Tuning 2 analysis in a grid.

This issue implements content for the function analysisSingleTuningTableHTML(), which currently holds placeholder text.

Proposed content

Reuse the layout and cell content from analysisNoteIntervalsHTML(), except using the same tuning on both the horizontal and vertical axis. 'Refectoring for reuse' might be beneficial.

Persist low-priority config changes

Split from #13

Perhaps selection of notes can be exempt, or on a debounced timer, so that selections and limits save infrequently.

If further analysis shows that this is all UI state, then close this issue.

Keyboard navigation and screen reader voicing

Currently, the SVG UI is not keyboard navigable, cannot take focus, and therefore provides no hints to screen readers.

  • Research how SVG elements can take keyboard focus
  • Research how SVG elements can have a keyboard-navigable hierarchy
  • Research the aria attributes necessary to generate voice prompts for screen readers.
  • Create voice prompts that give the important information as early as possible, to aid fast navigation.

User-entered data needs escaping

This would prevent corruption of the DOM, and execution of arbitrary code.
Fix the tuning names, in the Tuning properties dialog.
A function already exists in the code, escapeHTML().

To test check that 9-limit<script alert() /> doesn't corrupt the DOM, and doesn't show an alert.

non-12-ED sharp/flat naming

Find a consistent programmatic way of assigning sharp/flat labels and symbols to non-12-ED notes, especially with tunings having more than 12 divisions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.