001 002 package ibxm; 003 004 public class Envelope { 005 public boolean sustain, looped; 006 private int sustain_tick, loop_start_tick, loop_end_tick; 007 private int[] ticks, ampls; 008 009 public Envelope() { 010 set_num_points( 1 ); 011 } 012 013 public void set_num_points( int num_points ) { 014 int point; 015 if( num_points <= 0 ) { 016 num_points = 1; 017 } 018 ticks = new int[ num_points ]; 019 ampls = new int[ num_points ]; 020 set_point( 0, 0, 0, false ); 021 } 022 023 /* When you set a point, all subsequent points are reset. */ 024 public void set_point( int point, int tick, int ampl, boolean delta ) { 025 if( point >= 0 && point < ticks.length ) { 026 if( point == 0 ) { 027 tick = 0; 028 } 029 if( point > 0 ) { 030 if( delta ) tick += ticks[ point - 1 ]; 031 if( tick <= ticks[ point - 1 ] ) { 032 System.out.println( "Envelope: Point not valid (" + tick + " <= " + ticks[ point - 1 ] + ")"); 033 tick = ticks[ point - 1 ] + 1; 034 } 035 } 036 ticks[ point ] = tick; 037 ampls[ point ] = ampl; 038 point += 1; 039 while( point < ticks.length ) { 040 ticks[ point ] = ticks[ point - 1 ] + 1; 041 ampls[ point ] = 0; 042 point += 1; 043 } 044 } 045 } 046 047 public void set_sustain_point( int point ) { 048 if( point < 0 ) { 049 point = 0; 050 } 051 if( point >= ticks.length ) { 052 point = ticks.length - 1; 053 } 054 sustain_tick = ticks[ point ]; 055 } 056 057 public void set_loop_points( int start, int end ) { 058 if( start < 0 ) { 059 start = 0; 060 } 061 if( start >= ticks.length ) { 062 start = ticks.length - 1; 063 } 064 if( end < start || end >= ticks.length ) { 065 end = start; 066 } 067 loop_start_tick = ticks[ start ]; 068 loop_end_tick = ticks[ end ]; 069 } 070 071 public int next_tick( int tick, boolean key_on ) { 072 tick = tick + 1; 073 if( looped && tick >= loop_end_tick ) { 074 tick = loop_start_tick; 075 } 076 if( sustain && key_on && tick >= sustain_tick ) { 077 tick = sustain_tick; 078 } 079 return tick; 080 } 081 082 public int calculate_ampl( int tick ) { 083 int idx, point, delta_t, delta_a, ampl; 084 ampl = ampls[ ticks.length - 1 ]; 085 if( tick < ticks[ ticks.length - 1 ] ) { 086 point = 0; 087 for( idx = 1; idx < ticks.length; idx++ ) { 088 if( ticks[ idx ] <= tick ) { 089 point = idx; 090 } 091 } 092 delta_t = ticks[ point + 1 ] - ticks[ point ]; 093 delta_a = ampls[ point + 1 ] - ampls[ point ]; 094 ampl = ( delta_a << IBXM.FP_SHIFT ) / delta_t; 095 ampl = ampl * ( tick - ticks[ point ] ) >> IBXM.FP_SHIFT; 096 ampl = ampl + ampls[ point ]; 097 } 098 return ampl; 099 } 100 101 public void dump() { 102 int idx, tick; 103 for( idx = 0; idx < ticks.length; idx++ ) { 104 System.out.println( ticks[ idx ] + ", " + ampls[ idx ] ); 105 } 106 for( tick = 0; tick < 222; tick++ ) { 107 System.out.print( calculate_ampl( tick ) + ", " ); 108 } 109 } 110 } 111