import { SmartPlayer } from './SmartPlayer' ; import { Score , StretchNode , GainNode as GGainNode , Graph , LoopNode } from 'nf-grapher' ; import { SetValueAtTimeCmd } from './params/ScoreAudioParam' ; import { TimeInstant } from './time' ; import { Mutation , PushCommandsMutation , ClearCommandsMutation , MutationNames } from './Mutations' ; import 'web-audio-test-api' ; import { TestAudioContext } from './test-utils/TestAudioContext' ; import { ScriptProcessorRenderer } from './renderers/ScriptProcessorRenderer' ; test ( 'Apply PushCommandsEffectPayload Effect' , async ( ) => { const ctx = new AudioContext ( ) as TestAudioContext ; const renderer = new ScriptProcessorRenderer ( ctx ) ; const p = new SmartPlayer ( renderer ) ; p . playing = true ; const s = new Score ( ) ; const n = StretchNode . create ( ) ; s . graph . nodes . push ( n ) ; const c = { name : 'setValueAtTime' , args : { value : 1 , startTime : TimeInstant . fromSeconds ( 1 ) . asNanos ( ) } } ; const e = { name : MutationNames . PushCommands , nodeId : n . id , paramName : 'stretch' , commands : [ c ] } ; await p . setJson ( JSON . stringify ( s ) ) ; const result = p . enqueueMutation ( e ) ; ctx . $processTo ( '00:01.000' ) ; await result ; const uScore = JSON . parse ( p . getJson ( ) ) . pop ( ) ; expect ( uScore . graph . nodes [ 0 ] . params ! . stretch [ 0 ] ) . toEqual ( c ) ; } ) ; test ( 'Apply ClearCommandsEffectPayload Effect' , async ( ) => { const ctx = new AudioContext ( ) as TestAudioContext ; const renderer = new ScriptProcessorRenderer ( ctx ) ; const p = new SmartPlayer ( renderer ) ; p . playing = true ; const s = new Score ( ) ; const n = StretchNode . create ( ) ; n . stretch . setValueAtTime ( 1 , TimeInstant . fromSeconds ( 1 ) . asNanos ( ) ) ; s . graph . nodes . push ( n ) ; const e = { name : MutationNames . ClearCommands , nodeId : n . id , paramName : 'stretch' } ; await p . setJson ( JSON . stringify ( s ) ) ; const result = p . enqueueMutation ( e ) ; ctx . $processTo ( '00:01.000' ) ; await result ; const uScore = Score . from ( JSON . parse ( p . getJson ( ) ) . pop ( ) ) ; expect ( n . stretch . getCommands ( ) ) . toHaveLength ( 1 ) ; expect ( ( uScore . graph . nodes [ 0 ] as StretchNode ) . stretch . getCommands ( ) ) . toHaveLength ( 0 ) ; } ) ; test ( 'Enqueue/Dequeue a running Score' , async ( ) => { const ctx = new AudioContext ( ) as TestAudioContext ; const renderer = new ScriptProcessorRenderer ( ctx ) ; const p = new SmartPlayer ( renderer ) ; const s = new Score ( ) ; const n0 = GGainNode . create ( ) ; s . graph . nodes . push ( n0 ) ; await p . setJson ( JSON . stringify ( s ) ) ; const prevId = s . graph . id ; s . graph = new Graph ( undefined , undefined , s . graph . nodes , s . graph . edges ) ; const n2 = LoopNode . create ( { loopCount : - 1 , when : 0 , duration : TimeInstant . fromSeconds ( 1 ) . asNanos ( ) } ) ; const e1 = n0 . connectToTarget ( n2 ) ; s . graph . edges . push ( e1 ) ; s . graph . nodes . push ( n2 ) ; const enqueued = p . enqueueScore ( s ) ; const dequeued = p . dequeueScore ( prevId ) ; ctx . $processTo ( '00:01.000' ) ; await enqueued ; await dequeued ; const scores = JSON . parse ( p . getJson ( ) ) ; expect ( scores ) . toHaveLength ( 1 ) ; expect ( scores [ 0 ] ) . toEqual ( JSON . parse ( JSON . stringify ( s ) ) ) ; } ) ; test ( 'Grapher adjusts malformed Scores' , async ( ) => { const ctx = new AudioContext ( ) as TestAudioContext ; const renderer = new ScriptProcessorRenderer ( ctx ) ; const p = new SmartPlayer ( renderer ) ; const malformed = JSON . stringify ( { graph : { nodes : [ GGainNode . create ( ) ] } } ) ; const s = Score . from ( JSON . parse ( malformed ) ) ; await p . setJson ( JSON . stringify ( s ) ) ; expect ( JSON . parse ( p . getJson ( ) ) ) . toHaveLength ( 1 ) ; } ) ;