001
002 package ibxm;
003
004 public class IBXM {
005 public static final String VERSION = "ibxm alpha 51 (c)2008 mumart@gmail.com";
006
007 public static final int FP_SHIFT = 15;
008 public static final int FP_ONE = 1 << FP_SHIFT;
009 public static final int FP_MASK = FP_ONE - 1;
010
011 private int sampling_rate, resampling_quality, volume_ramp_length;
012 private int tick_length_samples, current_tick_samples;
013 private int[] mixing_buffer, volume_ramp_buffer;
014
015 private Module module;
016 private Channel[] channels;
017 private int[] global_volume, note;
018 private int current_sequence_index, next_sequence_index;
019 private int current_row, next_row;
020 private int tick_counter, ticks_per_row;
021 private int pattern_loop_count, pattern_loop_channel;
022
023 public IBXM( int sample_rate ) {
024
025 /** MODIFIED 13 Oct 2009 by Paul Lamb **/
026 // System.out.println( VERSION );
027 /***************************************/
028
029 if( sample_rate < 8000 ) {
030 sample_rate = 8000;
031 }
032 sampling_rate = sample_rate;
033 volume_ramp_length = sampling_rate >> 10;
034 volume_ramp_buffer = new int[ volume_ramp_length * 2 ];
035 mixing_buffer = new int[ sampling_rate / 6 ];
036 global_volume = new int[ 1 ];
037 note = new int[ 5 ];
038 set_module( new Module() );
039 set_resampling_quality( 1 );
040 }
041
042 public void set_module( Module m ) {
043 int channel_idx;
044 module = m;
045 channels = new Channel[ module.get_num_channels() ];
046 for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
047 channels[ channel_idx ] = new Channel( module, sampling_rate, global_volume );
048 }
049 set_sequence_index( 0, 0 );
050 }
051
052 public void set_resampling_quality( int quality ) {
053 resampling_quality = quality;
054 }
055
056 public int calculate_song_duration() {
057 int song_duration;
058 set_sequence_index( 0, 0 );
059 next_tick();
060 song_duration = tick_length_samples;
061 while( !next_tick() ) {
062 song_duration += tick_length_samples;
063 }
064 set_sequence_index( 0, 0 );
065 return song_duration;
066 }
067
068 public void set_sequence_index( int sequence_index, int row ) {
069 int channel_idx;
070 global_volume[ 0 ] = 64;
071 for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
072 channels[ channel_idx ].reset();
073 channels[ channel_idx ].set_panning( module.get_initial_panning( channel_idx ) );
074 }
075 set_global_volume( module.global_volume );
076 set_speed( 6 );
077 set_speed( module.default_speed );
078 set_tempo( 125 );
079 set_tempo( module.default_tempo );
080 pattern_loop_count = -1;
081 next_sequence_index = sequence_index;
082 next_row = row;
083 tick_counter = 0;
084 current_tick_samples = tick_length_samples;
085 clear_vol_ramp_buffer();
086 }
087
088 public void seek( int sample_position ) {
089 int idx;
090 set_sequence_index( 0, 0 );
091 next_tick();
092 while( sample_position > tick_length_samples ) {
093 sample_position -= tick_length_samples;
094 next_tick();
095 }
096 mix_tick();
097 current_tick_samples = sample_position;
098 }
099
100 public void get_audio( byte[] output_buffer, int frames ) {
101 int output_idx, mix_idx, mix_end, count, amplitude;
102 output_idx = 0;
103 while( frames > 0 ) {
104 count = tick_length_samples - current_tick_samples;
105 if( count > frames ) {
106 count = frames;
107 }
108 mix_idx = current_tick_samples << 1;
109 mix_end = mix_idx + ( count << 1 ) - 1;
110 while( mix_idx <= mix_end ) {
111 amplitude = mixing_buffer[ mix_idx ];
112 if( amplitude > 32767 ) {
113 amplitude = 32767;
114 }
115 if( amplitude < -32768 ) {
116 amplitude = -32768;
117 }
118 output_buffer[ output_idx ] = ( byte ) ( amplitude >> 8 );
119 output_buffer[ output_idx + 1 ] = ( byte ) ( amplitude & 0xFF );
120 output_idx += 2;
121 mix_idx += 1;
122 }
123 current_tick_samples = mix_idx >> 1;
124 frames -= count;
125 if( frames > 0 ) {
126 next_tick();
127 mix_tick();
128 current_tick_samples = 0;
129 }
130 }
131 }
132
133 private void mix_tick() {
134 int channel_idx, mix_idx, mix_len;
135 mix_idx = 0;
136 mix_len = tick_length_samples + volume_ramp_length << 1;
137 while( mix_idx < mix_len ) {
138 mixing_buffer[ mix_idx ] = 0;
139 mix_idx += 1;
140 }
141 for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
142 mix_len = tick_length_samples + volume_ramp_length;
143 channels[ channel_idx ].resample( mixing_buffer, 0, mix_len, resampling_quality );
144 }
145 volume_ramp();
146 }
147
148 private boolean next_tick() {
149 int channel_idx;
150 boolean song_end;
151 for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
152 channels[ channel_idx ].update_sample_idx( tick_length_samples );
153 }
154 tick_counter -= 1;
155 if( tick_counter <= 0 ) {
156 tick_counter = ticks_per_row;
157 song_end = next_row();
158 } else {
159 for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
160 channels[ channel_idx ].tick();
161 }
162 song_end = false;
163 }
164 return song_end;
165 }
166
167 private boolean next_row() {
168 int channel_idx, effect, effect_param;
169 boolean song_end;
170 Pattern pattern;
171 song_end = false;
172 if( next_sequence_index < 0 ) {
173 /* Bad next sequence index.*/
174 next_sequence_index = 0;
175 next_row = 0;
176 }
177 if( next_sequence_index >= module.get_sequence_length() ) {
178 /* End of sequence.*/
179 song_end = true;
180 next_sequence_index = module.restart_sequence_index;
181 if( next_sequence_index < 0 ) {
182 next_sequence_index = 0;
183 }
184 if( next_sequence_index >= module.get_sequence_length() ) {
185 next_sequence_index = 0;
186 }
187 next_row = 0;
188 }
189 if( next_sequence_index < current_sequence_index ) {
190 /* Jump to previous pattern. */
191 song_end = true;
192 }
193 if( next_sequence_index == current_sequence_index ) {
194 if( next_row <= current_row ) {
195 if( pattern_loop_count < 0 ) {
196 /* Jump to previous row in the same pattern, but not a pattern loop. */
197 song_end = true;
198 }
199 }
200 }
201 current_sequence_index = next_sequence_index;
202 pattern = module.get_pattern_from_sequence( current_sequence_index );
203 if( next_row < 0 || next_row >= pattern.num_rows ) {
204 /* Bad next row.*/
205 next_row = 0;
206 }
207 current_row = next_row;
208 next_row = current_row + 1;
209 if( next_row >= pattern.num_rows ) {
210 next_sequence_index = current_sequence_index + 1;
211 next_row = 0;
212 }
213 for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
214 pattern.get_note( note, current_row * channels.length + channel_idx );
215 effect = note[ 3 ];
216 effect_param = note[ 4 ];
217 channels[ channel_idx ].row( note[ 0 ], note[ 1 ], note[ 2 ], effect, effect_param );
218 switch( effect ) {
219 case 0x0B:
220 /* Pattern Jump.*/
221 if( pattern_loop_count < 0 ) {
222 next_sequence_index = effect_param;
223 next_row = 0;
224 }
225 break;
226 case 0x0D:
227 /* Pattern Break.*/
228 if( pattern_loop_count < 0 ) {
229 next_sequence_index = current_sequence_index + 1;
230 next_row = ( effect_param >> 4 ) * 10 + ( effect_param & 0x0F );
231 }
232 break;
233 case 0x0E:
234 /* Extended.*/
235 switch( effect_param & 0xF0 ) {
236 case 0x60:
237 /* Pattern loop.*/
238 if( ( effect_param & 0x0F ) == 0 ) {
239 /* Set loop marker on this channel. */
240 channels[ channel_idx ].pattern_loop_row = current_row;
241 }
242 if( channels[ channel_idx ].pattern_loop_row < current_row ) {
243 /* Marker and parameter are valid. Begin looping. */
244 if( pattern_loop_count < 0 ) {
245 /* Not already looping, begin. */
246 pattern_loop_count = effect_param & 0x0F;
247 pattern_loop_channel = channel_idx;
248 }
249 if( pattern_loop_channel == channel_idx ) {
250 /* Loop in progress on this channel. Next iteration. */
251 if( pattern_loop_count == 0 ) {
252 /* Loop finished. */
253 /* Invalidate current marker. */
254 channels[ channel_idx ].pattern_loop_row = current_row + 1;
255 } else {
256 /* Count must be higher than zero. */
257 /* Loop and cancel any breaks on this row. */
258 next_row = channels[ channel_idx ].pattern_loop_row;
259 next_sequence_index = current_sequence_index;
260 }
261 pattern_loop_count -= 1;
262 }
263 }
264 break;
265 case 0xE0:
266 /* Pattern delay.*/
267 tick_counter += ticks_per_row * ( effect_param & 0x0F );
268 break;
269 }
270 break;
271 case 0x0F:
272 /* Set Speed/Tempo.*/
273 if( effect_param < 32 ) {
274 set_speed( effect_param );
275 tick_counter = ticks_per_row;
276 } else {
277 set_tempo( effect_param );
278 }
279 break;
280 case 0x25:
281 /* S3M Set Speed.*/
282 set_speed( effect_param );
283 tick_counter = ticks_per_row;
284 break;
285 }
286 }
287 return song_end;
288 }
289
290 private void set_global_volume( int volume ) {
291 if( volume < 0 ) {
292 volume = 0;
293 }
294 if( volume > 64 ) {
295 volume = 64;
296 }
297 global_volume[ 0 ] = volume;
298 }
299
300 private void set_speed( int speed ) {
301 if( speed > 0 && speed < 256 ) {
302 ticks_per_row = speed;
303 }
304 }
305
306 private void set_tempo( int bpm ) {
307 if( bpm > 31 && bpm < 256 ) {
308 tick_length_samples = ( sampling_rate * 5 ) / ( bpm * 2 );
309 }
310 }
311
312 private void volume_ramp() {
313 int ramp_idx, next_idx, ramp_end;
314 int volume_ramp_delta, volume, sample;
315 sample = 0;
316 volume_ramp_delta = FP_ONE / volume_ramp_length;
317 volume = 0;
318 ramp_idx = 0;
319 next_idx = 2 * tick_length_samples;
320 ramp_end = volume_ramp_length * 2 - 1;
321 while( ramp_idx <= ramp_end ) {
322 sample = volume_ramp_buffer[ ramp_idx ] * ( FP_ONE - volume ) >> FP_SHIFT;
323 mixing_buffer[ ramp_idx ] = sample + ( mixing_buffer[ ramp_idx ] * volume >> FP_SHIFT );
324 volume_ramp_buffer[ ramp_idx ] = mixing_buffer[ next_idx + ramp_idx ];
325 sample = volume_ramp_buffer[ ramp_idx + 1 ] * ( FP_ONE - volume ) >> FP_SHIFT;
326 mixing_buffer[ ramp_idx + 1 ] = sample + ( mixing_buffer[ ramp_idx + 1 ] * volume >> FP_SHIFT );
327 volume_ramp_buffer[ ramp_idx + 1 ] = mixing_buffer[ next_idx + ramp_idx + 1 ];
328 volume += volume_ramp_delta;
329 ramp_idx += 2;
330 }
331 }
332
333 private void clear_vol_ramp_buffer() {
334 int ramp_idx, ramp_end;
335 ramp_idx = 0;
336 ramp_end = volume_ramp_length * 2 - 1;
337 while( ramp_idx <= ramp_end ) {
338 volume_ramp_buffer[ ramp_idx ] = 0;
339 ramp_idx += 1;
340 }
341 }
342 }
343