import { PlacementEnum , AbstractExpression } from "../AbstractExpression" ; import { MultiExpression } from "../MultiExpression" ; import { Fraction } from "../../../../Common/DataObjects/Fraction" ; import { SourceMeasure } from "../../SourceMeasure" ; export class ContinuousDynamicExpression extends AbstractExpression { constructor ( dynamicType , placement , staffNumber , measure , label = "" ) { super ( placement ) ; super . parentMeasure = measure ; this . dynamicType = dynamicType ; this . label = label ; this . staffNumber = staffNumber ; this . startVolume = - 1 ; this . endVolume = - 1 ; if ( label !== "" ) { this . setType ( ) ; } } private static listContinuousDynamicIncreasing : string [ ] = [ "crescendo" , "cresc" , "cresc." , "cres." ] ; private static listContinuousDynamicDecreasing : string [ ] = [ "decrescendo" , "decresc" , "decr." , "diminuendo" , "dim." , "dim" ] ; private dynamicType : ContDynamicEnum ; private startMultiExpression : MultiExpression ; private endMultiExpression : MultiExpression ; private startVolume : number ; private endVolume : number ; private staffNumber : number ; private label : string ; public get DynamicType ( ) : ContDynamicEnum { return this . dynamicType ; } public set DynamicType ( value ) { this . dynamicType = value ; } public get StartMultiExpression ( ) : MultiExpression { return this . startMultiExpression ; } public set StartMultiExpression ( value ) { this . startMultiExpression = value ; } public get EndMultiExpression ( ) : MultiExpression { return this . endMultiExpression ; } public set EndMultiExpression ( value ) { this . endMultiExpression = value ; } public get Placement ( ) : PlacementEnum { return this . placement ; } public set Placement ( value ) { this . placement = value ; } public get StartVolume ( ) : number { return this . startVolume ; } public set StartVolume ( value ) { this . startVolume = value ; } public get EndVolume ( ) : number { return this . endVolume ; } public set EndVolume ( value ) { this . endVolume = value ; } public get StaffNumber ( ) : number { return this . staffNumber ; } public set StaffNumber ( value ) { this . staffNumber = value ; } public get Label ( ) : string { return this . label ; } public set Label ( value ) { this . label = value ; this . setType ( ) ; } public static isInputStringContinuousDynamic ( inputString ) { if ( ! inputString ) { return false ; } return ( ContinuousDynamicExpression . isStringInStringList ( ContinuousDynamicExpression . listContinuousDynamicIncreasing , inputString ) || ContinuousDynamicExpression . isStringInStringList ( ContinuousDynamicExpression . listContinuousDynamicDecreasing , inputString ) ) ; } public getInterpolatedDynamic ( currentAbsoluteTimestamp ) { const continuousAbsoluteStartTimestamp = this . StartMultiExpression . AbsoluteTimestamp ; let continuousAbsoluteEndTimestamp ; if ( this . EndMultiExpression ) { continuousAbsoluteEndTimestamp = this . EndMultiExpression . AbsoluteTimestamp ; } else { continuousAbsoluteEndTimestamp = Fraction . plus ( this . startMultiExpression . SourceMeasureParent . AbsoluteTimestamp , this . startMultiExpression . SourceMeasureParent . Duration ) ; } if ( currentAbsoluteTimestamp . lt ( continuousAbsoluteStartTimestamp ) ) { return - 1 ; } if ( continuousAbsoluteEndTimestamp . lt ( currentAbsoluteTimestamp ) ) { return - 2 ; } const interpolationRatio = Fraction . minus ( currentAbsoluteTimestamp , continuousAbsoluteStartTimestamp ) . RealValue / Fraction . minus ( continuousAbsoluteEndTimestamp , continuousAbsoluteStartTimestamp ) . RealValue ; const interpolatedVolume = Math . max ( 0.0 , Math . min ( 99.9 , this . startVolume + ( this . endVolume - this . startVolume ) * interpolationRatio ) ) ; return interpolatedVolume ; } public isWedge ( ) { return ! this . label ; } private setType ( ) { if ( ContinuousDynamicExpression . isStringInStringList ( ContinuousDynamicExpression . listContinuousDynamicIncreasing , this . label ) ) { this . dynamicType = ContDynamicEnum . crescendo ; } else if ( ContinuousDynamicExpression . isStringInStringList ( ContinuousDynamicExpression . listContinuousDynamicDecreasing , this . label ) ) { this . dynamicType = ContDynamicEnum . diminuendo ; } } } export enum ContDynamicEnum { crescendo = 0 , /** Diminuendo/Decrescendo. These terms are apparently sometimes synonyms, and a falling wedge is given in MusicXML as type="diminuendo". */ diminuendo = 1 }