Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/ChannelItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export class ChannelItem {
*/
public value!: number;

/**
* Whether reset channels value to zero at the end of this item or not.
*/
public reset?: boolean;

/**
* This will only make sense when {@link curve} is specified.
* The time offset of the item.
Expand Down Expand Up @@ -67,6 +72,10 @@ export class ChannelItem {
}

public getValue( time: number ): number {
if ( this.reset && this.length <= time ) {
return 0.0;
}

if ( this.curve ) {
const t = this.offset! + time * this.speed!;
return this.value + this.amp * this.curve.getValue( t );
Expand All @@ -86,6 +95,7 @@ export class ChannelItem {
this.offset = data.offset ?? 0.0;
this.speed = data.speed ?? 1.0;
this.amp = data.amp ?? 1.0;
this.reset = data.reset;
if ( data.curve != null ) {
this.curve = this.__automaton.getCurve( data.curve )!;
this.length = data.length ?? this.curve.length ?? 0.0;
Expand Down
78 changes: 32 additions & 46 deletions src/tests/Channel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import { Automaton } from '../Automaton';
import { Channel } from '../Channel';
import type { SerializedAutomaton } from '../types/SerializedAutomaton';
import type { SerializedChannel } from '../types/SerializedChannel';

const data: SerializedAutomaton = {
resolution: 100.0,
Expand All @@ -14,68 +13,55 @@ const data: SerializedAutomaton = {
channels: {}
};

const serializedChannelWithALinearCurve: SerializedChannel = {
items: [ { curve: 0, time: 0.1 } ]
};

const serializedChannelWithAConstantCurve: SerializedChannel = {
items: [ { curve: 1, time: 0.1 } ]
};

describe( 'Channel', () => {
let automaton = new Automaton( data );

beforeEach( () => {
automaton = new Automaton( data );
} );

it( 'must be instantiated correctly (serializedChannelWithALinearCurve)', () => {
const channel = new Channel( automaton, serializedChannelWithALinearCurve );
expect( channel ).toBeInstanceOf( Channel );
} );

it( 'must be instantiated correctly (serializedChannelWithAConstantCurve)', () => {
const channel = new Channel( automaton, serializedChannelWithAConstantCurve );
it( 'must be instantiated correctly', () => {
const channel = new Channel( automaton, {
items: [ { curve: 0, time: 0.1 } ]
} );
expect( channel ).toBeInstanceOf( Channel );
} );

describe( 'getValue', () => {
let channelWithALinearCurve = new Channel( automaton, serializedChannelWithALinearCurve );
let channelWithAConstantCurve = new Channel( automaton, serializedChannelWithAConstantCurve );

beforeEach( () => {
channelWithALinearCurve = new Channel( automaton, serializedChannelWithALinearCurve );
channelWithAConstantCurve = new Channel( automaton, serializedChannelWithAConstantCurve );
} );

it( 'must return a proper value (channelWithALinearCurve, before the curve starts)', () => {
const result = channelWithALinearCurve.getValue( 0.05 );
expect( result ).toBeCloseTo( 0.0 );
} );

it( 'must return a proper value (channelWithAConstantCurve, before the curve starts)', () => {
const result = channelWithAConstantCurve.getValue( 0.05 );
expect( result ).toBeCloseTo( 0.0 );
} );

it( 'must return a proper value (channelWithALinearCurve, during the curve)', () => {
const result = channelWithALinearCurve.getValue( 0.4 );
expect( result ).toBeCloseTo( 0.5 );
it( 'must handle an item of a linear curve properly', () => {
const channel = new Channel( automaton, {
items: [ { curve: 0, time: 0.1 } ]
} );
expect( channel.getValue( 0.05 ) ).toBeCloseTo( 0.0 );
expect( channel.getValue( 0.4 ) ).toBeCloseTo( 0.5 );
expect( channel.getValue( 0.9 ) ).toBeCloseTo( 1.0 );
} );

it( 'must return a proper value (channelWithAConstantCurve, during the curve)', () => {
const result = channelWithAConstantCurve.getValue( 0.4 );
expect( result ).toBeCloseTo( 2.0 );
it( 'must handle an item of a constant curve properly', () => {
const channel = new Channel( automaton, {
items: [ { curve: 1, time: 0.1 } ]
} );
expect( channel.getValue( 0.05 ) ).toBeCloseTo( 0.0 );
expect( channel.getValue( 0.4 ) ).toBeCloseTo( 2.0 );
expect( channel.getValue( 0.9 ) ).toBeCloseTo( 2.0 );
} );

it( 'must return a proper value (channelWithALinearCurve, after the curve ends)', () => {
const result = channelWithALinearCurve.getValue( 0.9 );
expect( result ).toBeCloseTo( 1.0 );
it( 'must handle a constant item with reset properly', () => {
const channel = new Channel( automaton, {
items: [ { time: 0.5, length: 0.5, value: 1.0, reset: true } ]
} );
expect( channel.getValue( 0.3 ) ).toBeCloseTo( 0.0 );
expect( channel.getValue( 0.6 ) ).toBeCloseTo( 1.0 );
expect( channel.getValue( 1.2 ) ).toBeCloseTo( 0.0 );
} );

it( 'must return a proper value (channelWithAConstantCurve, after the curve ends)', () => {
const result = channelWithAConstantCurve.getValue( 0.9 );
expect( result ).toBeCloseTo( 2.0 );
it( 'must handle an item of a linear curve with reset properly', () => {
const channel = new Channel( automaton, {
items: [ { curve: 0, time: 0.1, reset: true } ]
} );
expect( channel.getValue( 0.05 ) ).toBeCloseTo( 0.0 );
expect( channel.getValue( 0.4 ) ).toBeCloseTo( 0.5 );
expect( channel.getValue( 0.9 ) ).toBeCloseTo( 0.0 );
} );
} );
} );
6 changes: 6 additions & 0 deletions src/types/SerializedChannelItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export interface SerializedChannelItem {
*/
value?: number;

/**
* Whether reset channels value to zero at the end of this item or not.
* `false` by default.
*/
reset?: boolean;

/**
* If it is not defined, interpret the item represents a constant item.
*/
Expand Down