111 lines
2.6 KiB
Java
111 lines
2.6 KiB
Java
|
|
package ibxm;
|
|
|
|
public class Envelope {
|
|
public boolean sustain, looped;
|
|
private int sustain_tick, loop_start_tick, loop_end_tick;
|
|
private int[] ticks, ampls;
|
|
|
|
public Envelope() {
|
|
set_num_points( 1 );
|
|
}
|
|
|
|
public void set_num_points( int num_points ) {
|
|
//int point; Forge: Unused
|
|
if( num_points <= 0 ) {
|
|
num_points = 1;
|
|
}
|
|
ticks = new int[ num_points ];
|
|
ampls = new int[ num_points ];
|
|
set_point( 0, 0, 0, false );
|
|
}
|
|
|
|
/* When you set a point, all subsequent points are reset. */
|
|
public void set_point( int point, int tick, int ampl, boolean delta ) {
|
|
if( point >= 0 && point < ticks.length ) {
|
|
if( point == 0 ) {
|
|
tick = 0;
|
|
}
|
|
if( point > 0 ) {
|
|
if( delta ) tick += ticks[ point - 1 ];
|
|
if( tick <= ticks[ point - 1 ] ) {
|
|
System.out.println( "Envelope: Point not valid (" + tick + " <= " + ticks[ point - 1 ] + ")");
|
|
tick = ticks[ point - 1 ] + 1;
|
|
}
|
|
}
|
|
ticks[ point ] = tick;
|
|
ampls[ point ] = ampl;
|
|
point += 1;
|
|
while( point < ticks.length ) {
|
|
ticks[ point ] = ticks[ point - 1 ] + 1;
|
|
ampls[ point ] = 0;
|
|
point += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void set_sustain_point( int point ) {
|
|
if( point < 0 ) {
|
|
point = 0;
|
|
}
|
|
if( point >= ticks.length ) {
|
|
point = ticks.length - 1;
|
|
}
|
|
sustain_tick = ticks[ point ];
|
|
}
|
|
|
|
public void set_loop_points( int start, int end ) {
|
|
if( start < 0 ) {
|
|
start = 0;
|
|
}
|
|
if( start >= ticks.length ) {
|
|
start = ticks.length - 1;
|
|
}
|
|
if( end < start || end >= ticks.length ) {
|
|
end = start;
|
|
}
|
|
loop_start_tick = ticks[ start ];
|
|
loop_end_tick = ticks[ end ];
|
|
}
|
|
|
|
public int next_tick( int tick, boolean key_on ) {
|
|
tick = tick + 1;
|
|
if( looped && tick >= loop_end_tick ) {
|
|
tick = loop_start_tick;
|
|
}
|
|
if( sustain && key_on && tick >= sustain_tick ) {
|
|
tick = sustain_tick;
|
|
}
|
|
return tick;
|
|
}
|
|
|
|
public int calculate_ampl( int tick ) {
|
|
int idx, point, delta_t, delta_a, ampl;
|
|
ampl = ampls[ ticks.length - 1 ];
|
|
if( tick < ticks[ ticks.length - 1 ] ) {
|
|
point = 0;
|
|
for( idx = 1; idx < ticks.length; idx++ ) {
|
|
if( ticks[ idx ] <= tick ) {
|
|
point = idx;
|
|
}
|
|
}
|
|
delta_t = ticks[ point + 1 ] - ticks[ point ];
|
|
delta_a = ampls[ point + 1 ] - ampls[ point ];
|
|
ampl = ( delta_a << IBXM.FP_SHIFT ) / delta_t;
|
|
ampl = ampl * ( tick - ticks[ point ] ) >> IBXM.FP_SHIFT;
|
|
ampl = ampl + ampls[ point ];
|
|
}
|
|
return ampl;
|
|
}
|
|
|
|
public void dump() {
|
|
int idx, tick;
|
|
for( idx = 0; idx < ticks.length; idx++ ) {
|
|
System.out.println( ticks[ idx ] + ", " + ampls[ idx ] );
|
|
}
|
|
for( tick = 0; tick < 222; tick++ ) {
|
|
System.out.print( calculate_ampl( tick ) + ", " );
|
|
}
|
|
}
|
|
}
|
|
|