import { ModificationBase, NoteDetails } from './ModificationBase.mjs';
import * as WebAudioApiErrors from '../modules/Errors.mjs';
/**
* Class representing a Global Dynamic modification.
*
* A Global Dynamic modification causes all subsequent notes to be played either softer
* or louder than average.
*
* @extends ModificationBase
*/
export class GlobalDynamic extends ModificationBase {
// Effect-specific private variables
/** @type {number} */
#degreeOfDynamic;
// Conversion from degrees to velocity
static degreesConversion = [
0.1, 0.1, 0.2, 0.2, 0.3, 0.3, 0.4, 0.45, 0.5,
0.55, 0.6, 0.6, 0.75, 0.75, 0.85, 0.85, 0.95, 0.95 ];
/**
* Constructs a new {@link GlobalDynamic} modification object.
*
* @param {number} degreeOfDynamic - Number of dynamic symbols to apply (0.5 for mezzo-dynamics, negative for pianos)
*/
constructor(degreeOfDynamic, tempo, key, details) {
super(tempo, key, details);
this.#degreeOfDynamic = degreeOfDynamic;
}
/**
* Returns a list of all parameters available for use in this modification, including whether
* the parameter is required or optional when playing back either a "sequence" or just a
* single "note".
*
* @returns {Object<string,Object<string,string[]>>} List of modification-specific parameter keys and when they are required
*/
static getParameters() {
return {
required: {
singleNote: [],
sequence: []
},
optional: {
singleNote: [],
sequence: []
}
};
}
/**
* Returns whether this modification can be used to modify a sequence of notes.
*
* @returns {boolean} Whether this modification can be used to modify a sequence of notes
*/
static canModifySequence() {
return false;
}
static inferParametersFromSequence() {
throw new WebAudioApiErrors.WebAudioValueError('The "GlobalDynamic" modification cannot infer any parameters from a sequence of notes');
}
getModifiedNoteDetails() {
return [new NoteDetails(
this.unmodifiedDetails.note,
GlobalDynamic.degreesConversion[(this.#degreeOfDynamic * 2) + 8],
this.unmodifiedDetails.duration
)];
}
}