56#ifndef INCLUDE_JAR_XM_H
57#define INCLUDE_JAR_XM_H
62#define JAR_XM_DEFENSIVE 1
67 #define JARXM_MALLOC(sz) malloc(sz)
70 #define JARXM_FREE(p) free(p)
74struct jar_xm_context_s;
126 float* musicBuffer =
JARXM_MALLOC((2*numsamples)*
sizeof(
float));
130 for(
int x=0;x<2*numsamples;x++) output[x] = (musicBuffer[x] * 32767.0f);
139 float* musicBuffer =
JARXM_MALLOC((2*numsamples)*
sizeof(
float));
143 for(
int x=0;x<2*numsamples;x++) output[x] = (musicBuffer[x] * 127.0f);
227#ifdef JAR_XM_IMPLEMENTATION
237#define DEBUG(fmt, ...) do { \
238 fprintf(stderr, "%s(): " fmt "\n", __func__, __VA_ARGS__); \
246#error "Big endian platforms are not yet supported, sorry"
248extern int __fail[-1];
252#define SAMPLE_NAME_LENGTH 22
253#define INSTRUMENT_NAME_LENGTH 22
254#define MODULE_NAME_LENGTH 20
255#define TRACKER_NAME_LENGTH 20
256#define PATTERN_ORDER_TABLE_LENGTH 256
258#define NUM_ENVELOPE_POINTS 12
259#define MAX_NUM_ROWS 256
261#define jar_xm_SAMPLE_RAMPING_POINTS 8
265enum jar_xm_waveform_type_e {
266 jar_xm_SINE_WAVEFORM = 0,
267 jar_xm_RAMP_DOWN_WAVEFORM = 1,
268 jar_xm_SQUARE_WAVEFORM = 2,
269 jar_xm_RANDOM_WAVEFORM = 3,
270 jar_xm_RAMP_UP_WAVEFORM = 4,
272typedef enum jar_xm_waveform_type_e jar_xm_waveform_type_t;
274enum jar_xm_loop_type_e {
277 jar_xm_PING_PONG_LOOP,
279typedef enum jar_xm_loop_type_e jar_xm_loop_type_t;
281enum jar_xm_frequency_type_e {
282 jar_xm_LINEAR_FREQUENCIES,
283 jar_xm_AMIGA_FREQUENCIES,
285typedef enum jar_xm_frequency_type_e jar_xm_frequency_type_t;
287struct jar_xm_envelope_point_s {
291typedef struct jar_xm_envelope_point_s jar_xm_envelope_point_t;
293struct jar_xm_envelope_s {
294 jar_xm_envelope_point_t points[NUM_ENVELOPE_POINTS];
300 bool sustain_enabled;
303typedef struct jar_xm_envelope_s jar_xm_envelope_t;
305struct jar_xm_sample_s {
306 char name[SAMPLE_NAME_LENGTH + 1];
315 jar_xm_loop_type_t loop_type;
322 typedef struct jar_xm_sample_s jar_xm_sample_t;
324 struct jar_xm_instrument_s {
325 char name[INSTRUMENT_NAME_LENGTH + 1];
327 uint8_t sample_of_notes[NUM_NOTES];
328 jar_xm_envelope_t volume_envelope;
329 jar_xm_envelope_t panning_envelope;
330 jar_xm_waveform_type_t vibrato_type;
338 jar_xm_sample_t* samples;
340 typedef struct jar_xm_instrument_s jar_xm_instrument_t;
342 struct jar_xm_pattern_slot_s {
349 typedef struct jar_xm_pattern_slot_s jar_xm_pattern_slot_t;
351 struct jar_xm_pattern_s {
353 jar_xm_pattern_slot_t* slots;
355 typedef struct jar_xm_pattern_s jar_xm_pattern_t;
357 struct jar_xm_module_s {
358 char name[MODULE_NAME_LENGTH + 1];
359 char trackername[TRACKER_NAME_LENGTH + 1];
367 jar_xm_frequency_type_t frequency_type;
368 uint8_t pattern_table[PATTERN_ORDER_TABLE_LENGTH];
370 jar_xm_pattern_t* patterns;
371 jar_xm_instrument_t* instruments;
373 typedef struct jar_xm_module_s jar_xm_module_t;
375 struct jar_xm_channel_context_s {
378 jar_xm_instrument_t* instrument;
380 jar_xm_pattern_slot_t* current;
382 float sample_position;
394 float fadeout_volume;
395 float volume_envelope_volume;
396 float panning_envelope_panning;
397 uint16_t volume_envelope_frame_count;
398 uint16_t panning_envelope_frame_count;
400 float autovibrato_note_offset;
402 bool arp_in_progress;
405 uint8_t fine_volume_slide_param;
406 uint8_t global_volume_slide_param;
410 uint8_t fine_portamento_up_param;
411 uint8_t fine_portamento_down_param;
412 uint8_t extra_fine_portamento_up_param;
413 uint8_t extra_fine_portamento_down_param;
415 float tone_portamento_target_period;
420 bool vibrato_in_progress;
421 jar_xm_waveform_type_t vibrato_waveform;
422 bool vibrato_waveform_retrigger;
425 float vibrato_note_offset;
426 jar_xm_waveform_type_t tremolo_waveform;
427 bool tremolo_waveform_retrigger;
430 float tremolo_volume;
438 float target_panning;
441 unsigned long frame_count;
442 float end_of_previous_sample_left[jar_xm_SAMPLE_RAMPING_POINTS];
443 float end_of_previous_sample_right[jar_xm_SAMPLE_RAMPING_POINTS];
447 float actual_panning;
450 typedef struct jar_xm_channel_context_s jar_xm_channel_context_t;
452 struct jar_xm_context_s {
453 void* allocated_memory;
459 float default_global_volume;
471 float remaining_samples_in_tick;
485 jar_xm_channel_context_t* channels;
492int jar_xm_check_sanity_preload(
const char*,
size_t);
511size_t jar_xm_get_memory_needed_for_context(
const char*,
size_t);
521#define ALIGN(x, b) (((x) + ((b) - 1)) & ~((b) - 1))
522#define ALIGN_PTR(x, b) (void*)(((uintptr_t)(x) + ((b) - 1)) & ~((b) - 1))
532 if((ret = jar_xm_check_sanity_preload(moddata, moddata_length))) {
533 DEBUG(
"jar_xm_check_sanity_preload() returned %i, module is not safe to load", ret);
538 bytes_needed = jar_xm_get_memory_needed_for_context(moddata, moddata_length);
540 if(mempool ==
NULL && bytes_needed > 0) {
541 DEBUG(
"call to JARXM_MALLOC() failed, returned %p", (
void*)mempool);
546 memset(mempool, 0, bytes_needed);
549 ctx->allocated_memory = mempool;
553 mempool = jar_xm_load_module(ctx, moddata, moddata_length, mempool);
554 mempool = ALIGN_PTR(mempool, 16);
556 ctx->channels = (jar_xm_channel_context_t*)mempool;
557 mempool += ctx->module.num_channels *
sizeof(jar_xm_channel_context_t);
558 mempool = ALIGN_PTR(mempool, 16);
560 ctx->default_global_volume = 1.f;
561 ctx->global_volume = ctx->default_global_volume;
563 ctx->volume_ramp = (1.f / 128.f);
564 ctx->panning_ramp = (1.f / 128.f);
566 for(
uint8_t i = 0; i < ctx->module.num_channels; ++i) {
567 jar_xm_channel_context_t *ch = ctx->channels + i;
569 ch->vibrato_waveform = jar_xm_SINE_WAVEFORM;
570 ch->vibrato_waveform_retrigger =
true;
571 ch->tremolo_waveform = jar_xm_SINE_WAVEFORM;
572 ch->tremolo_waveform_retrigger =
true;
573 ch->volume = ch->volume_envelope_volume = ch->fadeout_volume = 1.0f;
574 ch->panning = ch->panning_envelope_panning = .5f;
575 ch->actual_volume = .0f;
576 ch->actual_panning = .5f;
579 mempool = ALIGN_PTR(mempool, 16);
580 ctx->row_loop_count = (
uint8_t *)mempool;
581 mempool += MAX_NUM_ROWS *
sizeof(
uint8_t);
584 if((ret = jar_xm_check_sanity_postload(ctx))) { DEBUG(
"jar_xm_check_sanity_postload() returned %i, module is not safe to play", ret);
598 ctx->max_loop_count = loopcnt;
602 return ctx->loop_count;
606 bool old = ctx->channels[
channel - 1].muted;
607 ctx->channels[
channel - 1].muted = mute;
612 bool old = ctx->module.instruments[instr - 1].muted;
613 ctx->module.instruments[instr - 1].muted = mute;
618 return ctx->module.name;
622 return ctx->module.trackername;
626 return ctx->module.num_channels;
630 return ctx->module.length;
634 return ctx->module.num_patterns;
638 return ctx->module.patterns[pattern].num_rows;
642 return ctx->module.num_instruments;
646 return ctx->module.instruments[instrument - 1].num_samples;
650 if(bpm) *bpm = ctx->bpm;
651 if(tempo) *tempo = ctx->tempo;
655 if(pattern_index) *pattern_index = ctx->current_table_index;
656 if(pattern) *pattern = ctx->module.pattern_table[ctx->current_table_index];
657 if(row) *row = ctx->current_row;
658 if(samples) *samples = ctx->generated_samples;
662 return ctx->module.instruments[instr - 1].latest_trigger;
666 return ctx->module.instruments[instr - 1].samples[
sample].latest_trigger;
670 return ctx->channels[chn - 1].latest_trigger;
677#define READ_U8(offset) (((offset) < moddata_length) ? (*(uint8_t*)(moddata + (offset))) : 0)
678#define READ_U16(offset) ((uint16_t)READ_U8(offset) | ((uint16_t)READ_U8((offset) + 1) << 8))
679#define READ_U32(offset) ((uint32_t)READ_U16(offset) | ((uint32_t)READ_U16((offset) + 2) << 16))
680#define READ_MEMCPY(ptr, offset, length) memcpy_pad(ptr, length, moddata, moddata_length, offset)
682static void memcpy_pad(
void *dst,
size_t dst_len,
const void *src,
size_t src_len,
size_t offset) {
687 size_t copy_bytes = (src_len >= offset) ? (src_len - offset) : 0;
688 copy_bytes = copy_bytes > dst_len ? dst_len : copy_bytes;
690 memcpy(dst_c, src_c + offset, copy_bytes);
692 memset(dst_c + copy_bytes, 0, dst_len - copy_bytes);
697int jar_xm_check_sanity_preload(
const char*
module,
size_t module_length) {
698 if(module_length < 60) {
return 4; }
699 if(memcmp(
"Extended Module: ",
module, 17) != 0) {
return 1; }
700 if(
module[37] != 0x1A) {
return 2; }
701 if(
module[59] != 0x01 ||
module[58] != 0x04) {
return 3; }
707 for(
uint8_t i = 0; i < ctx->module.length; ++i) {
708 if(ctx->module.pattern_table[i] >= ctx->module.num_patterns) {
709 if(i+1 == ctx->module.length && ctx->module.length > 1) {
710 DEBUG(
"trimming invalid POT at pos %X", i);
711 --ctx->module.length;
713 DEBUG(
"module has invalid POT, pos %X references nonexistent pattern %X", i, ctx->module.pattern_table[i]);
724size_t jar_xm_get_memory_needed_for_context(
const char* moddata,
size_t moddata_length) {
725 size_t memory_needed = 0;
732 num_channels = READ_U16(offset + 8);
733 num_patterns = READ_U16(offset + 10);
734 memory_needed += num_patterns *
sizeof(jar_xm_pattern_t);
735 memory_needed = ALIGN(memory_needed, 16);
736 num_instruments = READ_U16(offset + 12);
737 memory_needed += num_instruments *
sizeof(jar_xm_instrument_t);
738 memory_needed = ALIGN(memory_needed, 16);
739 memory_needed += MAX_NUM_ROWS * READ_U16(offset + 4) *
sizeof(
uint8_t);
741 offset += READ_U32(offset);
744 for(
uint16_t i = 0; i < num_patterns; ++i) {
746 num_rows = READ_U16(offset + 5);
747 memory_needed += num_rows * num_channels *
sizeof(jar_xm_pattern_slot_t);
748 offset += READ_U32(offset) + READ_U16(offset + 7);
750 memory_needed = ALIGN(memory_needed, 16);
753 for(
uint16_t i = 0; i < num_instruments; ++i) {
757 num_samples = READ_U16(offset + 27);
758 memory_needed += num_samples *
sizeof(jar_xm_sample_t);
759 if(num_samples > 0) { sample_header_size = READ_U32(offset + 29); }
761 offset += READ_U32(offset);
762 for(
uint16_t j = 0; j < num_samples; ++j) {
765 sample_size = READ_U32(offset);
766 flags = READ_U8(offset + 14);
767 sample_size_aggregate += sample_size;
769 if(flags & (1 << 4)) {
770 memory_needed += sample_size * (
sizeof(float) >> 1);
772 memory_needed += sample_size *
sizeof(float);
774 offset += sample_header_size;
776 offset += sample_size_aggregate;
779 memory_needed += num_channels *
sizeof(jar_xm_channel_context_t);
781 return memory_needed;
784char* jar_xm_load_module(
jar_xm_context_t* ctx,
const char* moddata,
size_t moddata_length,
char* mempool) {
786 jar_xm_module_t* mod = &(ctx->module);
789 READ_MEMCPY(mod->name, offset + 17, MODULE_NAME_LENGTH);
790 READ_MEMCPY(mod->trackername, offset + 38, TRACKER_NAME_LENGTH);
794 uint32_t header_size = READ_U32(offset);
795 mod->length = READ_U16(offset + 4);
796 mod->restart_position = READ_U16(offset + 6);
797 mod->num_channels = READ_U16(offset + 8);
798 mod->num_patterns = READ_U16(offset + 10);
799 mod->num_instruments = READ_U16(offset + 12);
800 mod->patterns = (jar_xm_pattern_t*)mempool;
801 mod->linear_interpolation = 1;
803 mempool += mod->num_patterns *
sizeof(jar_xm_pattern_t);
804 mempool = ALIGN_PTR(mempool, 16);
805 mod->instruments = (jar_xm_instrument_t*)mempool;
806 mempool += mod->num_instruments *
sizeof(jar_xm_instrument_t);
807 mempool = ALIGN_PTR(mempool, 16);
808 uint16_t flags = READ_U32(offset + 14);
809 mod->frequency_type = (flags & (1 << 0)) ? jar_xm_LINEAR_FREQUENCIES : jar_xm_AMIGA_FREQUENCIES;
810 ctx->default_tempo = READ_U16(offset + 16);
811 ctx->default_bpm = READ_U16(offset + 18);
812 ctx->tempo =ctx->default_tempo;
813 ctx->bpm = ctx->default_bpm;
815 READ_MEMCPY(mod->pattern_table, offset + 20, PATTERN_ORDER_TABLE_LENGTH);
816 offset += header_size;
819 for(
uint16_t i = 0; i < mod->num_patterns; ++i) {
820 uint16_t packed_patterndata_size = READ_U16(offset + 7);
821 jar_xm_pattern_t* pat = mod->patterns + i;
822 pat->num_rows = READ_U16(offset + 5);
823 pat->slots = (jar_xm_pattern_slot_t*)mempool;
824 mempool += mod->num_channels * pat->num_rows *
sizeof(jar_xm_pattern_slot_t);
825 offset += READ_U32(offset);
827 if(packed_patterndata_size == 0) {
828 memset(pat->slots, 0,
sizeof(jar_xm_pattern_slot_t) * pat->num_rows * mod->num_channels);
831 for(
uint16_t j = 0, k = 0; j < packed_patterndata_size; ++k) {
833 jar_xm_pattern_slot_t* slot = pat->slots + k;
834 if(
note & (1 << 7)) {
837 if(
note & (1 << 0)) {
838 slot->note = READ_U8(offset + j);
843 if(
note & (1 << 1)) {
844 slot->instrument = READ_U8(offset + j);
847 slot->instrument = 0;
849 if(
note & (1 << 2)) {
850 slot->volume_column = READ_U8(offset + j);
853 slot->volume_column = 0;
855 if(
note & (1 << 3)) {
856 slot->effect_type = READ_U8(offset + j);
859 slot->effect_type = 0;
861 if(
note & (1 << 4)) {
862 slot->effect_param = READ_U8(offset + j);
865 slot->effect_param = 0;
869 slot->instrument = READ_U8(offset + j + 1);
870 slot->volume_column = READ_U8(offset + j + 2);
871 slot->effect_type = READ_U8(offset + j + 3);
872 slot->effect_param = READ_U8(offset + j + 4);
878 offset += packed_patterndata_size;
880 mempool = ALIGN_PTR(mempool, 16);
883 for(
uint16_t i = 0; i < ctx->module.num_instruments; ++i) {
885 jar_xm_instrument_t* instr = mod->instruments + i;
887 READ_MEMCPY(instr->name, offset + 4, INSTRUMENT_NAME_LENGTH);
888 instr->num_samples = READ_U16(offset + 27);
890 if(instr->num_samples > 0) {
892 sample_header_size = READ_U32(offset + 29);
893 READ_MEMCPY(instr->sample_of_notes, offset + 33, NUM_NOTES);
895 instr->volume_envelope.num_points = READ_U8(offset + 225);
896 instr->panning_envelope.num_points = READ_U8(offset + 226);
898 for(
uint8_t j = 0; j < instr->volume_envelope.num_points; ++j) {
899 instr->volume_envelope.points[j].frame = READ_U16(offset + 129 + 4 * j);
900 instr->volume_envelope.points[j].value = READ_U16(offset + 129 + 4 * j + 2);
903 for(
uint8_t j = 0; j < instr->panning_envelope.num_points; ++j) {
904 instr->panning_envelope.points[j].frame = READ_U16(offset + 177 + 4 * j);
905 instr->panning_envelope.points[j].value = READ_U16(offset + 177 + 4 * j + 2);
908 instr->volume_envelope.sustain_point = READ_U8(offset + 227);
909 instr->volume_envelope.loop_start_point = READ_U8(offset + 228);
910 instr->volume_envelope.loop_end_point = READ_U8(offset + 229);
911 instr->panning_envelope.sustain_point = READ_U8(offset + 230);
912 instr->panning_envelope.loop_start_point = READ_U8(offset + 231);
913 instr->panning_envelope.loop_end_point = READ_U8(offset + 232);
915 uint8_t flags = READ_U8(offset + 233);
916 instr->volume_envelope.enabled = flags & (1 << 0);
917 instr->volume_envelope.sustain_enabled = flags & (1 << 1);
918 instr->volume_envelope.loop_enabled = flags & (1 << 2);
920 flags = READ_U8(offset + 234);
921 instr->panning_envelope.enabled = flags & (1 << 0);
922 instr->panning_envelope.sustain_enabled = flags & (1 << 1);
923 instr->panning_envelope.loop_enabled = flags & (1 << 2);
924 instr->vibrato_type = READ_U8(offset + 235);
925 if(instr->vibrato_type == 2) {
926 instr->vibrato_type = 1;
927 }
else if(instr->vibrato_type == 1) {
928 instr->vibrato_type = 2;
930 instr->vibrato_sweep = READ_U8(offset + 236);
931 instr->vibrato_depth = READ_U8(offset + 237);
932 instr->vibrato_rate = READ_U8(offset + 238);
933 instr->volume_fadeout = READ_U16(offset + 239);
934 instr->samples = (jar_xm_sample_t*)mempool;
935 mempool += instr->num_samples *
sizeof(jar_xm_sample_t);
937 instr->samples =
NULL;
941 offset += READ_U32(offset);
943 for(
int j = 0; j < instr->num_samples; ++j) {
945 jar_xm_sample_t*
sample = instr->samples + j;
948 sample->loop_start = READ_U32(offset + 4);
949 sample->loop_length = READ_U32(offset + 8);
951 sample->
volume = (float)(READ_U8(offset + 12) << 2) / 256.f;
955 uint8_t flags = READ_U8(offset + 14);
959 sample->loop_type = jar_xm_PING_PONG_LOOP;
961 sample->loop_type = jar_xm_FORWARD_LOOP;
964 sample->loop_type = jar_xm_NO_LOOP;
967 sample->bits = (flags & 0x10) ? 16 : 8;
968 sample->stereo = (flags & 0x20) ? 1 : 0;
969 sample->panning = (float)READ_U8(offset + 15) / 255.f;
971 READ_MEMCPY(
sample->
name, 18, SAMPLE_NAME_LENGTH);
972 sample->data = (
float*)mempool;
977 sample->loop_length >>= 1;
985 if (
sample->stereo &&
sample->loop_type != jar_xm_NO_LOOP) {
986 div_t lstart = div(READ_U32(offset + 4), 2);
987 sample->loop_start = lstart.quot;
988 div_t llength = div(READ_U32(offset + 8), 2);
989 sample->loop_length = llength.quot;
993 offset += sample_header_size;
997 for(
int j = 0; j < instr->num_samples; ++j) {
999 jar_xm_sample_t*
sample = instr->samples + j;
1006 for(
int k = 0; k < length; ++k) {
1007 if (k == result.quot) { v = 0;};
1008 v = v + (
int16_t)READ_U16(offset + (k << 1));
1009 sample->data[k] = (float) v / 32768.f ;
1015 for(
int k = 0; k < length; ++k) {
1016 if (k == result.quot) { v = 0;};
1017 v = v + (
int8_t)READ_U8(offset + k);
1018 sample->data[k] = (float)v / 128.f ;
1027 for(
int k = 0; k < length; ++k) {
1028 v = v + (
int16_t)READ_U16(offset + (k << 1));
1029 sample->data[k] = (float) v / 32768.f ;
1035 for(
int k = 0; k < length; ++k) {
1036 v = v + (
int8_t)READ_U8(offset + k);
1037 sample->data[k] = (float)v / 128.f ;
1050static float jar_xm_waveform(jar_xm_waveform_type_t,
uint8_t);
1051static void jar_xm_autovibrato(
jar_xm_context_t*, jar_xm_channel_context_t*);
1055static void jar_xm_tone_portamento(
jar_xm_context_t*, jar_xm_channel_context_t*);
1056static void jar_xm_pitch_slide(
jar_xm_context_t*, jar_xm_channel_context_t*,
float);
1057static void jar_xm_panning_slide(jar_xm_channel_context_t*,
uint8_t);
1058static void jar_xm_volume_slide(jar_xm_channel_context_t*,
uint8_t);
1060static float jar_xm_envelope_lerp(jar_xm_envelope_point_t*, jar_xm_envelope_point_t*,
uint16_t);
1061static void jar_xm_envelope_tick(jar_xm_channel_context_t*, jar_xm_envelope_t*,
uint16_t*,
float*);
1062static void jar_xm_envelopes(jar_xm_channel_context_t*);
1064static float jar_xm_linear_period(
float);
1065static float jar_xm_linear_frequency(
float);
1066static float jar_xm_amiga_period(
float);
1067static float jar_xm_amiga_frequency(
float);
1070static void jar_xm_update_frequency(
jar_xm_context_t*, jar_xm_channel_context_t*);
1072static void jar_xm_handle_note_and_instrument(
jar_xm_context_t*, jar_xm_channel_context_t*, jar_xm_pattern_slot_t*);
1073static void jar_xm_trigger_note(
jar_xm_context_t*, jar_xm_channel_context_t*,
unsigned int flags);
1074static void jar_xm_cut_note(jar_xm_channel_context_t*);
1075static void jar_xm_key_off(jar_xm_channel_context_t*);
1081static void jar_xm_next_of_sample(
jar_xm_context_t*, jar_xm_channel_context_t*,
int);
1084#define jar_xm_TRIGGER_KEEP_VOLUME (1 << 0)
1085#define jar_xm_TRIGGER_KEEP_PERIOD (1 << 1)
1086#define jar_xm_TRIGGER_KEEP_SAMPLE_POSITION (1 << 2)
1089static const uint16_t amiga_frequencies[] = { 1712, 1616, 1525, 1440, 1357, 1281, 1209, 1141, 1077, 1017, 961, 907, 856 };
1092static const float multi_retrig_add[] = { 0.f, -1.f, -2.f, -4.f, -8.f, -16.f, 0.f, 0.f, 0.f, 1.f, 2.f, 4.f, 8.f, 16.f, 0.f, 0.f };
1095static const float multi_retrig_multiply[] = { 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, .6666667f, .5f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.5f, 2.f };
1097#define jar_xm_CLAMP_UP1F(vol, limit) do { \
1098 if((vol) > (limit)) (vol) = (limit); \
1100#define jar_xm_CLAMP_UP(vol) jar_xm_CLAMP_UP1F((vol), 1.f)
1102#define jar_xm_CLAMP_DOWN1F(vol, limit) do { \
1103 if((vol) < (limit)) (vol) = (limit); \
1105#define jar_xm_CLAMP_DOWN(vol) jar_xm_CLAMP_DOWN1F((vol), .0f)
1107#define jar_xm_CLAMP2F(vol, up, down) do { \
1108 if((vol) > (up)) (vol) = (up); \
1109 else if((vol) < (down)) (vol) = (down); \
1111#define jar_xm_CLAMP(vol) jar_xm_CLAMP2F((vol), 1.f, .0f)
1113#define jar_xm_SLIDE_TOWARDS(val, goal, incr) do { \
1114 if((val) > (goal)) { \
1116 jar_xm_CLAMP_DOWN1F((val), (goal)); \
1117 } else if((val) < (goal)) { \
1119 jar_xm_CLAMP_UP1F((val), (goal)); \
1123#define jar_xm_LERP(u, v, t) ((u) + (t) * ((v) - (u)))
1124#define jar_xm_INVERSE_LERP(u, v, lerp) (((lerp) - (u)) / ((v) - (u)))
1126#define HAS_TONE_PORTAMENTO(s) ((s)->effect_type == 3 \
1127 || (s)->effect_type == 5 \
1128 || ((s)->volume_column >> 4) == 0xF)
1129#define HAS_ARPEGGIO(s) ((s)->effect_type == 0 \
1130 && (s)->effect_param != 0)
1131#define HAS_VIBRATO(s) ((s)->effect_type == 4 \
1132 || (s)->effect_param == 6 \
1133 || ((s)->volume_column >> 4) == 0xB)
1134#define NOTE_IS_VALID(n) ((n) > 0 && (n) < 97)
1137static float jar_xm_waveform(jar_xm_waveform_type_t waveform,
uint8_t step) {
1138 static unsigned int next_rand = 24492;
1141 case jar_xm_SINE_WAVEFORM:
1142 return -sinf(2.f * 3.141592f * (
float)step / (
float)0x40);
1143 case jar_xm_RAMP_DOWN_WAVEFORM:
1144 return (
float)(0x20 - step) / 0x20;
1145 case jar_xm_SQUARE_WAVEFORM:
1146 return (step >= 0x20) ? 1.f : -1.f;
1147 case jar_xm_RANDOM_WAVEFORM:
1148 next_rand = next_rand * 1103515245 + 12345;
1149 return (
float)((next_rand >> 16) & 0x7FFF) / (float)0x4000 - 1.f;
1150 case jar_xm_RAMP_UP_WAVEFORM:
1151 return (
float)(step - 0x20) / 0x20;
1158static void jar_xm_autovibrato(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch) {
1159 if(ch->instrument ==
NULL || ch->instrument->vibrato_depth == 0)
return;
1160 jar_xm_instrument_t* instr = ch->instrument;
1162 if(ch->autovibrato_ticks < instr->vibrato_sweep) { sweep = jar_xm_LERP(0.f, 1.f, (
float)ch->autovibrato_ticks / (
float)instr->vibrato_sweep); }
1163 unsigned int step = ((ch->autovibrato_ticks++) * instr->vibrato_rate) >> 2;
1164 ch->autovibrato_note_offset = .25f * jar_xm_waveform(instr->vibrato_type, step) * (float)instr->vibrato_depth / (
float)0xF * sweep;
1165 jar_xm_update_frequency(ctx, ch);
1169 unsigned int step = pos * (param >> 4);
1170 ch->vibrato_note_offset = 2.f * jar_xm_waveform(ch->vibrato_waveform, step) * (float)(param & 0x0F) / (float)0xF;
1171 jar_xm_update_frequency(ctx, ch);
1175 unsigned int step = pos * (param >> 4);
1176 ch->tremolo_volume = -1.f * jar_xm_waveform(ch->tremolo_waveform, step) * (float)(param & 0x0F) / (float)0xF;
1182 ch->arp_in_progress =
false;
1183 ch->arp_note_offset = 0;
1186 ch->arp_in_progress =
true;
1187 ch->arp_note_offset = param >> 4;
1190 ch->arp_in_progress =
true;
1191 ch->arp_note_offset = param & 0x0F;
1194 jar_xm_update_frequency(ctx, ch);
1197static void jar_xm_tone_portamento(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch) {
1199 if(ch->tone_portamento_target_period == 0.f)
return;
1200 if(ch->period != ch->tone_portamento_target_period) {
1201 jar_xm_SLIDE_TOWARDS(ch->period, ch->tone_portamento_target_period, (ctx->module.frequency_type == jar_xm_LINEAR_FREQUENCIES ? 4.f : 1.f) * ch->tone_portamento_param);
1202 jar_xm_update_frequency(ctx, ch);
1206static void jar_xm_pitch_slide(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch,
float period_offset) {
1208 if(ctx->module.frequency_type == jar_xm_LINEAR_FREQUENCIES) {period_offset *= 4.f; }
1209 ch->period += period_offset;
1210 jar_xm_CLAMP_DOWN(ch->period);
1212 jar_xm_update_frequency(ctx, ch);
1215static void jar_xm_panning_slide(jar_xm_channel_context_t* ch,
uint8_t rawval) {
1216 if (rawval & 0xF0) {ch->panning += (float)((rawval & 0xF0 )>> 4) / (
float)0xFF;};
1217 if (rawval & 0x0F) {ch->panning -= (float)(rawval & 0x0F) / (float)0xFF;};
1220static void jar_xm_volume_slide(jar_xm_channel_context_t* ch,
uint8_t rawval) {
1221 if (rawval & 0xF0) {ch->volume += (float)((rawval & 0xF0) >> 4) / (
float)0x40;};
1222 if (rawval & 0x0F) {ch->volume -= (float)(rawval & 0x0F) / (float)0x40;};
1225static float jar_xm_envelope_lerp(jar_xm_envelope_point_t* a, jar_xm_envelope_point_t* b,
uint16_t pos) {
1227 if(pos <= a->frame)
return a->value;
1228 else if(pos >= b->frame)
return b->value;
1230 float p = (float)(pos - a->frame) / (float)(b->frame - a->frame);
1231 return a->value * (1 - p) + b->value * p;
1237 if(ctx->current_table_index >= ctx->module.length) {
1238 ctx->current_table_index = ctx->module.restart_position;
1239 ctx->tempo =ctx->default_tempo;
1240 ctx->bpm = ctx->default_bpm;
1241 ctx->global_volume = ctx->default_global_volume;
1245static float jar_xm_linear_period(
float note) {
1246 return 7680.f -
note * 64.f;
1249static float jar_xm_linear_frequency(
float period) {
1250 return 8363.f * powf(2.f, (4608.f - period) / 768.f);
1253static float jar_xm_amiga_period(
float note) {
1254 unsigned int intnote =
note;
1257 uint16_t p1 = amiga_frequencies[a], p2 = amiga_frequencies[a + 1];
1261 }
else if(octave < 0) {
1265 return jar_xm_LERP(p1, p2,
note - intnote);
1268static float jar_xm_amiga_frequency(
float period) {
1269 if(period == .0f)
return .0f;
1270 return 7093789.2f / (period * 2.f);
1274 switch(ctx->module.frequency_type) {
1275 case jar_xm_LINEAR_FREQUENCIES:
1276 return jar_xm_linear_period(
note);
1277 case jar_xm_AMIGA_FREQUENCIES:
1278 return jar_xm_amiga_period(
note);
1283static float jar_xm_frequency(
jar_xm_context_t* ctx,
float period,
float note_offset) {
1284 switch(ctx->module.frequency_type) {
1285 case jar_xm_LINEAR_FREQUENCIES:
1286 return jar_xm_linear_frequency(period - 64.f * note_offset);
1287 case jar_xm_AMIGA_FREQUENCIES:
1288 if(note_offset == 0) {
return jar_xm_amiga_frequency(period); };
1295 if(period > amiga_frequencies[0]) {
1297 while(period > (amiga_frequencies[0] << -octave)) --octave;
1298 }
else if(period < amiga_frequencies[12]) {
1300 while(period < (amiga_frequencies[12] >> octave)) ++octave;
1304 for(
uint8_t i = 0; i < 12; ++i) {
1305 p1 = amiga_frequencies[i], p2 = amiga_frequencies[i + 1];
1309 }
else if(octave < 0) {
1313 if(p2 <= period && period <= p1) {
1318 if(
JAR_XM_DEBUG && (p1 < period || p2 > period)) { DEBUG(
"%i <= %f <= %i should hold but doesn't, this is a bug", p2, period, p1); }
1319 note = 12.f * (octave + 2) + a + jar_xm_INVERSE_LERP(p1, p2, period);
1320 return jar_xm_amiga_frequency(jar_xm_amiga_period(
note + note_offset));
1326static void jar_xm_update_frequency(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch) {
1327 ch->frequency = jar_xm_frequency( ctx, ch->period, (ch->arp_note_offset > 0 ? ch->arp_note_offset : ( ch->vibrato_note_offset + ch->autovibrato_note_offset )) );
1328 ch->step = ch->frequency / ctx->rate;
1331static void jar_xm_handle_note_and_instrument(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch, jar_xm_pattern_slot_t* s) {
1332 jar_xm_module_t* mod = &(ctx->module);
1333 if(s->instrument > 0) {
1334 if(HAS_TONE_PORTAMENTO(ch->current) && ch->instrument !=
NULL && ch->sample !=
NULL) {
1335 jar_xm_trigger_note(ctx, ch, jar_xm_TRIGGER_KEEP_PERIOD | jar_xm_TRIGGER_KEEP_SAMPLE_POSITION);
1336 }
else if(s->instrument > ctx->module.num_instruments) {
1337 jar_xm_cut_note(ch);
1338 ch->instrument =
NULL;
1341 ch->instrument = ctx->module.instruments + (s->instrument - 1);
1342 if(s->note == 0 && ch->sample !=
NULL) {
1344 jar_xm_trigger_note(ctx, ch, jar_xm_TRIGGER_KEEP_SAMPLE_POSITION);
1349 if(NOTE_IS_VALID(s->note)) {
1351 jar_xm_instrument_t* instr = ch->instrument;
1352 if(HAS_TONE_PORTAMENTO(ch->current) && instr !=
NULL && ch->sample !=
NULL) {
1354 ch->note = s->note + ch->sample->relative_note + ch->sample->finetune / 128.f - 1.f;
1355 ch->tone_portamento_target_period = jar_xm_period(ctx, ch->note);
1356 }
else if(instr ==
NULL || ch->instrument->num_samples == 0) {
1357 jar_xm_cut_note(ch);
1359 if(instr->sample_of_notes[s->note - 1] < instr->num_samples) {
1361 for(
int i = 0; i < jar_xm_SAMPLE_RAMPING_POINTS; ++i) {
1362 jar_xm_next_of_sample(ctx, ch, i);
1364 ch->frame_count = 0;
1366 ch->sample = instr->samples + instr->sample_of_notes[s->note - 1];
1367 ch->orig_note = ch->note = s->note + ch->sample->relative_note + ch->sample->finetune / 128.f - 1.f;
1368 if(s->instrument > 0) {
1369 jar_xm_trigger_note(ctx, ch, 0);
1371 jar_xm_trigger_note(ctx, ch, jar_xm_TRIGGER_KEEP_VOLUME);
1374 jar_xm_cut_note(ch);
1377 }
else if(s->note == NOTE_OFF) {
1382 switch(s->effect_type) {
1384 if(s->effect_param > 0) { ch->portamento_up_param = s->effect_param; }
1387 if(s->effect_param > 0) { ch->portamento_down_param = s->effect_param; }
1390 if(s->effect_param > 0) { ch->tone_portamento_param = s->effect_param; }
1393 if(s->effect_param & 0x0F) { ch->vibrato_param = (ch->vibrato_param & 0xF0) | (s->effect_param & 0x0F); }
1394 if(s->effect_param >> 4) { ch->vibrato_param = (s->effect_param & 0xF0) | (ch->vibrato_param & 0x0F); }
1397 if(s->effect_param > 0) { ch->volume_slide_param = s->effect_param; }
1400 if(s->effect_param > 0) { ch->volume_slide_param = s->effect_param; }
1403 if(s->effect_param & 0x0F) { ch->tremolo_param = (ch->tremolo_param & 0xF0) | (s->effect_param & 0x0F); }
1404 if(s->effect_param >> 4) { ch->tremolo_param = (s->effect_param & 0xF0) | (ch->tremolo_param & 0x0F); }
1407 ch->panning = (float)s->effect_param / 255.f;
1410 if(ch->sample != 0) {
1411 uint32_t final_offset = s->effect_param << (ch->sample->bits == 16 ? 7 : 8);
1412 switch (ch->sample->loop_type) {
1413 case jar_xm_NO_LOOP:
1414 if(final_offset >= ch->sample->length) {
1415 ch->sample_position = -1;
1417 ch->sample_position = final_offset;
1420 case jar_xm_FORWARD_LOOP:
1421 if (final_offset >= ch->sample->loop_end) {
1422 ch->sample_position -= ch->sample->loop_length;
1423 }
else if(final_offset >= ch->sample->length) {
1424 ch->sample_position = ch->sample->loop_start;
1426 ch->sample_position = final_offset;
1429 case jar_xm_PING_PONG_LOOP:
1430 if(final_offset >= ch->sample->loop_end) {
1432 ch->sample_position = (ch->sample->loop_end << 1) - ch->sample_position;
1433 }
else if(final_offset >= ch->sample->length) {
1435 ch->sample_position -= ch->sample->length - 1;
1437 ch->sample_position = final_offset;
1444 if(s->effect_param > 0) { ch->volume_slide_param = s->effect_param; }
1447 if(s->effect_param < ctx->module.length) {
1448 ctx->position_jump =
true;
1449 ctx->jump_dest = s->effect_param;
1453 ch->volume = (float)((s->effect_param > 0x40) ? 0x40 : s->effect_param) / (
float)0x40;
1457 ctx->pattern_break =
true;
1458 ctx->jump_row = (s->effect_param >> 4) * 10 + (s->effect_param & 0x0F);
1461 switch(s->effect_param >> 4) {
1463 if(s->effect_param & 0x0F) { ch->fine_portamento_up_param = s->effect_param & 0x0F; }
1464 jar_xm_pitch_slide(ctx, ch, -ch->fine_portamento_up_param);
1467 if(s->effect_param & 0x0F) { ch->fine_portamento_down_param = s->effect_param & 0x0F; }
1468 jar_xm_pitch_slide(ctx, ch, ch->fine_portamento_down_param);
1471 ch->vibrato_waveform = s->effect_param & 3;
1472 ch->vibrato_waveform_retrigger = !((s->effect_param >> 2) & 1);
1475 if(NOTE_IS_VALID(ch->current->note) && ch->sample !=
NULL) {
1476 ch->note = ch->current->note + ch->sample->relative_note + (float)(((s->effect_param & 0x0F) - 8) << 4) / 128.f - 1.f;
1477 ch->period = jar_xm_period(ctx, ch->note);
1478 jar_xm_update_frequency(ctx, ch);
1482 if(s->effect_param & 0x0F) {
1483 if((s->effect_param & 0x0F) == ch->pattern_loop_count) {
1484 ch->pattern_loop_count = 0;
1485 ctx->position_jump =
false;
1487 ch->pattern_loop_count++;
1488 ctx->position_jump =
true;
1489 ctx->jump_row = ch->pattern_loop_origin;
1490 ctx->jump_dest = ctx->current_table_index;
1493 ch->pattern_loop_origin = ctx->current_row;
1494 ctx->jump_row = ch->pattern_loop_origin;
1498 ch->tremolo_waveform = s->effect_param & 3;
1499 ch->tremolo_waveform_retrigger = !((s->effect_param >> 2) & 1);
1502 if(s->effect_param & 0x0F) { ch->fine_volume_slide_param = s->effect_param & 0x0F; }
1503 jar_xm_volume_slide(ch, ch->fine_volume_slide_param << 4);
1506 if(s->effect_param & 0x0F) { ch->fine_volume_slide_param = s->effect_param & 0x0F; }
1507 jar_xm_volume_slide(ch, ch->fine_volume_slide_param);
1511 if(s->note == 0 && s->instrument == 0) {
1512 unsigned int flags = jar_xm_TRIGGER_KEEP_VOLUME;
1513 if(ch->current->effect_param & 0x0F) {
1514 ch->note = ch->orig_note;
1515 jar_xm_trigger_note(ctx, ch, flags);
1517 jar_xm_trigger_note(ctx, ch, flags | jar_xm_TRIGGER_KEEP_PERIOD | jar_xm_TRIGGER_KEEP_SAMPLE_POSITION );
1523 ctx->extra_ticks = (ch->current->effect_param & 0x0F) * ctx->tempo;
1531 if(s->effect_param > 0) {
1532 if(s->effect_param <= 0x1F) {
1533 ctx->tempo = s->effect_param;
1535 ctx->bpm = s->effect_param;
1541 ctx->global_volume = (float)((s->effect_param > 0x40) ? 0x40 : s->effect_param) / (
float)0x40;
1544 if(s->effect_param > 0) { ch->global_volume_slide_param = s->effect_param; }
1547 ch->volume_envelope_frame_count = s->effect_param;
1548 ch->panning_envelope_frame_count = s->effect_param;
1551 if(s->effect_param > 0) { ch->panning_slide_param = s->effect_param; }
1554 if(s->effect_param > 0) {
1555 if((s->effect_param >> 4) == 0) {
1556 ch->multi_retrig_param = (ch->multi_retrig_param & 0xF0) | (s->effect_param & 0x0F);
1558 ch->multi_retrig_param = s->effect_param;
1563 if(s->effect_param > 0) { ch->tremor_param = s->effect_param; }
1566 switch(s->effect_param >> 4) {
1568 if(s->effect_param & 0x0F) { ch->extra_fine_portamento_up_param = s->effect_param & 0x0F; }
1569 jar_xm_pitch_slide(ctx, ch, -1.0f * ch->extra_fine_portamento_up_param);
1572 if(s->effect_param & 0x0F) { ch->extra_fine_portamento_down_param = s->effect_param & 0x0F; }
1573 jar_xm_pitch_slide(ctx, ch, ch->extra_fine_portamento_down_param);
1584static void jar_xm_trigger_note(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch,
unsigned int flags) {
1585 if (!(flags & jar_xm_TRIGGER_KEEP_SAMPLE_POSITION)) {
1586 ch->sample_position = 0.f;
1590 if (!(flags & jar_xm_TRIGGER_KEEP_VOLUME)) {
1591 if(ch->sample !=
NULL) {
1592 ch->volume = ch->sample->volume;
1595 ch->panning = ch->sample->panning;
1596 ch->sustained =
true;
1597 ch->fadeout_volume = ch->volume_envelope_volume = 1.0f;
1598 ch->panning_envelope_panning = .5f;
1599 ch->volume_envelope_frame_count = ch->panning_envelope_frame_count = 0;
1600 ch->vibrato_note_offset = 0.f;
1601 ch->tremolo_volume = 0.f;
1602 ch->tremor_on =
false;
1603 ch->autovibrato_ticks = 0;
1605 if(ch->vibrato_waveform_retrigger) { ch->vibrato_ticks = 0; }
1606 if(ch->tremolo_waveform_retrigger) { ch->tremolo_ticks = 0; }
1607 if(!(flags & jar_xm_TRIGGER_KEEP_PERIOD)) {
1608 ch->period = jar_xm_period(ctx, ch->note);
1609 jar_xm_update_frequency(ctx, ch);
1611 ch->latest_trigger = ctx->generated_samples;
1612 if(ch->instrument !=
NULL) { ch->instrument->latest_trigger = ctx->generated_samples; }
1613 if(ch->sample !=
NULL) { ch->sample->latest_trigger = ctx->generated_samples; }
1616static void jar_xm_cut_note(jar_xm_channel_context_t* ch) {
1622static void jar_xm_key_off(jar_xm_channel_context_t* ch) {
1623 ch->sustained =
false;
1624 if(ch->instrument ==
NULL || !ch->instrument->volume_envelope.enabled) { jar_xm_cut_note(ch); }
1628 if(ctx->position_jump) {
1629 ctx->current_table_index = ctx->jump_dest;
1630 ctx->current_row = ctx->jump_row;
1631 ctx->position_jump =
false;
1632 ctx->pattern_break =
false;
1634 jar_xm_post_pattern_change(ctx);
1635 }
else if(ctx->pattern_break) {
1636 ctx->current_table_index++;
1637 ctx->current_row = ctx->jump_row;
1638 ctx->pattern_break =
false;
1640 jar_xm_post_pattern_change(ctx);
1642 jar_xm_pattern_t* cur = ctx->module.patterns + ctx->module.pattern_table[ctx->current_table_index];
1643 bool in_a_loop =
false;
1646 for(
uint8_t i = 0; i < ctx->module.num_channels; ++i) {
1647 jar_xm_pattern_slot_t* s = cur->slots + ctx->current_row * ctx->module.num_channels + i;
1648 jar_xm_channel_context_t* ch = ctx->channels + i;
1651 if(s->effect_type != 0xE || s->effect_param >> 4 != 0xD) {
1653 jar_xm_handle_note_and_instrument(ctx, ch, s);
1656 ch->note_delay_param = s->effect_param & 0x0F;
1658 if(!in_a_loop && ch->pattern_loop_count > 0) {
1666 ctx->loop_count = (ctx->row_loop_count[MAX_NUM_ROWS * ctx->current_table_index + ctx->current_row]++);
1671 if (!ctx->position_jump && !ctx->pattern_break && (ctx->current_row >= cur->num_rows || ctx->current_row == 0)) {
1672 ctx->current_table_index++;
1673 ctx->current_row = ctx->jump_row;
1675 jar_xm_post_pattern_change(ctx);
1679static void jar_xm_envelope_tick(jar_xm_channel_context_t *ch, jar_xm_envelope_t *env,
uint16_t *counter,
float *outval) {
1680 if(env->num_points < 2) {
1681 if(env->num_points == 1) {
1682 *outval = (float)env->points[0].value / (
float)0x40;
1683 if(*outval > 1) { *outval = 1; };
1688 if(env->loop_enabled) {
1689 uint16_t loop_start = env->points[env->loop_start_point].frame;
1690 uint16_t loop_end = env->points[env->loop_end_point].frame;
1691 uint16_t loop_length = loop_end - loop_start;
1692 if(*counter >= loop_end) { *counter -= loop_length; };
1694 for(
uint8_t j = 0; j < (env->num_points - 1); ++j) {
1695 if(env->points[j].frame <= *counter && env->points[j+1].frame >= *counter) {
1696 *outval = jar_xm_envelope_lerp(env->points + j, env->points + j + 1, *counter) / (float)0x40;
1701 if(!ch->sustained || !env->sustain_enabled || *counter != env->points[env->sustain_point].frame) { (*counter)++; };
1705static void jar_xm_envelopes(jar_xm_channel_context_t *ch) {
1706 if(ch->instrument !=
NULL) {
1707 if(ch->instrument->volume_envelope.enabled) {
1708 if(!ch->sustained) {
1709 ch->fadeout_volume -= (float)ch->instrument->volume_fadeout / 65536.f;
1710 jar_xm_CLAMP_DOWN(ch->fadeout_volume);
1712 jar_xm_envelope_tick(ch, &(ch->instrument->volume_envelope), &(ch->volume_envelope_frame_count), &(ch->volume_envelope_volume));
1714 if(ch->instrument->panning_envelope.enabled) {
1715 jar_xm_envelope_tick(ch, &(ch->instrument->panning_envelope), &(ch->panning_envelope_frame_count), &(ch->panning_envelope_panning));
1721 if(ctx->current_tick == 0) {
1725 jar_xm_module_t* mod = &(ctx->module);
1726 for(
uint8_t i = 0; i < ctx->module.num_channels; ++i) {
1727 jar_xm_channel_context_t* ch = ctx->channels + i;
1728 jar_xm_envelopes(ch);
1729 jar_xm_autovibrato(ctx, ch);
1730 if(ch->arp_in_progress && !HAS_ARPEGGIO(ch->current)) {
1731 ch->arp_in_progress =
false;
1732 ch->arp_note_offset = 0;
1733 jar_xm_update_frequency(ctx, ch);
1735 if(ch->vibrato_in_progress && !HAS_VIBRATO(ch->current)) {
1736 ch->vibrato_in_progress =
false;
1737 ch->vibrato_note_offset = 0.f;
1738 jar_xm_update_frequency(ctx, ch);
1742 switch(ch->current->volume_column & 0xF0) {
1744 if(ch->current->volume_column != 0x50)
break;
1749 ch->volume = (float)(ch->current->volume_column - 16) / 64.0f;
1752 jar_xm_volume_slide(ch, ch->current->volume_column & 0x0F);
1755 jar_xm_volume_slide(ch, ch->current->volume_column << 4);
1758 jar_xm_volume_slide(ch, ch->current->volume_column & 0x0F);
1761 jar_xm_volume_slide(ch, ch->current->volume_column << 4);
1764 ch->vibrato_param = (ch->vibrato_param & 0x0F) | ((ch->current->volume_column & 0x0F) << 4);
1767 ch->vibrato_in_progress =
false;
1768 jar_xm_vibrato(ctx, ch, ch->vibrato_param, ch->vibrato_ticks++);
1771 if(!ctx->current_tick ) {
1772 ch->panning = (float)(ch->current->volume_column & 0x0F) / 15.0f;
1776 jar_xm_panning_slide(ch, ch->current->volume_column & 0x0F);
1779 jar_xm_panning_slide(ch, ch->current->volume_column << 4);
1782 if(!ctx->current_tick ) {
1783 if(ch->current->volume_column & 0x0F) { ch->tone_portamento_param = ((ch->current->volume_column & 0x0F) << 4) | (ch->current->volume_column & 0x0F); }
1785 jar_xm_tone_portamento(ctx, ch);
1793 switch(ch->current->effect_type) {
1795 if(ch->current->effect_param > 0) {
1796 char arp_offset = ctx->tempo % 3;
1797 switch(arp_offset) {
1799 if(ctx->current_tick == 1) {
1800 ch->arp_in_progress =
true;
1801 ch->arp_note_offset = ch->current->effect_param >> 4;
1802 jar_xm_update_frequency(ctx, ch);
1807 if(ctx->current_tick == 0) {
1808 ch->arp_in_progress =
false;
1809 ch->arp_note_offset = 0;
1810 jar_xm_update_frequency(ctx, ch);
1815 jar_xm_arpeggio(ctx, ch, ch->current->effect_param, ctx->current_tick - arp_offset);
1823 if(ctx->current_tick == 0)
break;
1824 jar_xm_pitch_slide(ctx, ch, -ch->portamento_up_param);
1827 if(ctx->current_tick == 0)
break;
1828 jar_xm_pitch_slide(ctx, ch, ch->portamento_down_param);
1831 if(ctx->current_tick == 0)
break;
1832 jar_xm_tone_portamento(ctx, ch);
1835 if(ctx->current_tick == 0)
break;
1836 ch->vibrato_in_progress =
true;
1837 jar_xm_vibrato(ctx, ch, ch->vibrato_param, ch->vibrato_ticks++);
1840 if(ctx->current_tick == 0)
break;
1841 jar_xm_tone_portamento(ctx, ch);
1842 jar_xm_volume_slide(ch, ch->volume_slide_param);
1845 if(ctx->current_tick == 0)
break;
1846 ch->vibrato_in_progress =
true;
1847 jar_xm_vibrato(ctx, ch, ch->vibrato_param, ch->vibrato_ticks++);
1848 jar_xm_volume_slide(ch, ch->volume_slide_param);
1851 if(ctx->current_tick == 0)
break;
1852 jar_xm_tremolo(ctx, ch, ch->tremolo_param, ch->tremolo_ticks++);
1859 if(ctx->current_tick == 0)
break;
1860 jar_xm_volume_slide(ch, ch->volume_slide_param);
1863 switch(ch->current->effect_param >> 4) {
1865 if(ctx->current_tick != 0 && ch->current->effect_param & 0x0F) {
1866 if(!(ctx->current_tick % (ch->current->effect_param & 0x0F))) {
1867 jar_xm_trigger_note(ctx, ch, 0);
1868 jar_xm_envelopes(ch);
1873 if((ch->current->effect_param & 0x0F) == ctx->current_tick) {
1874 jar_xm_cut_note(ch);
1878 if(ch->note_delay_param == ctx->current_tick) {
1879 jar_xm_handle_note_and_instrument(ctx, ch, ch->current);
1880 jar_xm_envelopes(ch);
1890 if(ctx->current_tick == 0)
break;
1891 if((ch->global_volume_slide_param & 0xF0) && (ch->global_volume_slide_param & 0x0F)) {
break; };
1892 if(ch->global_volume_slide_param & 0xF0) {
1893 float f = (float)(ch->global_volume_slide_param >> 4) / (float)0x40;
1894 ctx->global_volume += f;
1895 jar_xm_CLAMP_UP(ctx->global_volume);
1897 float f = (float)(ch->global_volume_slide_param & 0x0F) / (float)0x40;
1898 ctx->global_volume -= f;
1899 jar_xm_CLAMP_DOWN(ctx->global_volume);
1904 if(ctx->current_tick == ch->current->effect_param) { jar_xm_key_off(ch); };
1909 if(ctx->current_tick == 0)
break;
1910 jar_xm_panning_slide(ch, ch->panning_slide_param);
1913 if(ctx->current_tick == 0)
break;
1914 if(((ch->multi_retrig_param) & 0x0F) == 0)
break;
1915 if((ctx->current_tick % (ch->multi_retrig_param & 0x0F)) == 0) {
1916 float v = ch->volume * multi_retrig_multiply[ch->multi_retrig_param >> 4]
1917 + multi_retrig_add[ch->multi_retrig_param >> 4];
1919 jar_xm_trigger_note(ctx, ch, 0);
1925 if(ctx->current_tick == 0)
break;
1926 ch->tremor_on = ( (ctx->current_tick - 1) % ((ch->tremor_param >> 4) + (ch->tremor_param & 0x0F) + 2) > (ch->tremor_param >> 4) );
1932 float panning, volume;
1933 panning = ch->panning + (ch->panning_envelope_panning - .5f) * (.5f - fabs(ch->panning - .5f)) * 2.0f;
1937 volume = ch->volume + ch->tremolo_volume;
1938 jar_xm_CLAMP(volume);
1939 volume *= ch->fadeout_volume * ch->volume_envelope_volume;
1943 ch->target_panning = panning;
1944 ch->target_volume = volume;
1946 ch->actual_panning = panning;
1947 ch->actual_volume = volume;
1951 ctx->current_tick++;
1952 if(ctx->current_tick >= ctx->tempo + ctx->extra_ticks) {
1954 ctx->current_tick = 0;
1955 ctx->extra_ticks = 0;
1959 ctx->remaining_samples_in_tick += (float)ctx->rate / ((
float)ctx->bpm * 0.4f);
1962static void jar_xm_next_of_sample(
jar_xm_context_t* ctx, jar_xm_channel_context_t* ch,
int previous) {
1963 jar_xm_module_t* mod = &(ctx->module);
1967 if(ch->instrument ==
NULL || ch->sample ==
NULL || ch->sample_position < 0) {
1968 ch->curr_left = 0.f;
1969 ch->curr_right = 0.f;
1971 if (ch->frame_count < jar_xm_SAMPLE_RAMPING_POINTS) {
1972 if (previous > -1) {
1973 ch->end_of_previous_sample_left[previous] = jar_xm_LERP(ch->end_of_previous_sample_left[ch->frame_count], ch->curr_left, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
1974 ch->end_of_previous_sample_right[previous] = jar_xm_LERP(ch->end_of_previous_sample_right[ch->frame_count], ch->curr_right, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
1976 ch->curr_left = jar_xm_LERP(ch->end_of_previous_sample_left[ch->frame_count], ch->curr_left, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
1977 ch->curr_right = jar_xm_LERP(ch->end_of_previous_sample_right[ch->frame_count], ch->curr_right, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
1983 if(ch->sample->length == 0) {
1989 if(mod->linear_interpolation) {
1990 b = ch->sample_position + 1;
1991 t = ch->sample_position - (
uint32_t)ch->sample_position;
1994 float u_left, u_right;
1995 u_left = ch->sample->data[(
uint32_t)ch->sample_position];
1996 if (ch->sample->stereo) {
1997 u_right = ch->sample->data[(
uint32_t)ch->sample_position + ch->sample->length];
2001 float v_left = 0.f, v_right = 0.f;
2002 switch(ch->sample->loop_type) {
2003 case jar_xm_NO_LOOP:
2004 if(mod->linear_interpolation) {
2005 v_left = (b < ch->sample->length) ? ch->sample->data[b] : .0f;
2006 if (ch->sample->stereo) {
2007 v_right = (b < ch->sample->length) ? ch->sample->data[b + ch->sample->length] : .0f;
2012 ch->sample_position += ch->step;
2013 if(ch->sample_position >= ch->sample->length) { ch->sample_position = -1; }
2015 case jar_xm_FORWARD_LOOP:
2016 if(mod->linear_interpolation) {
2017 v_left = ch->sample->data[ (b == ch->sample->loop_end) ? ch->sample->loop_start : b ];
2018 if (ch->sample->stereo) {
2019 v_right = ch->sample->data[ (b == ch->sample->loop_end) ? ch->sample->loop_start + ch->sample->length : b + ch->sample->length];
2024 ch->sample_position += ch->step;
2025 if (ch->sample_position >= ch->sample->loop_end) {
2026 ch->sample_position -= ch->sample->loop_length;
2028 if(ch->sample_position >= ch->sample->length) {
2029 ch->sample_position = ch->sample->loop_start;
2032 case jar_xm_PING_PONG_LOOP:
2034 if(mod->linear_interpolation) {
2035 v_left = (b >= ch->sample->loop_end) ? ch->sample->data[(
uint32_t)ch->sample_position] : ch->sample->data[b];
2036 if (ch->sample->stereo) {
2037 v_right = (b >= ch->sample->loop_end) ? ch->sample->data[(
uint32_t)ch->sample_position + ch->sample->length] : ch->sample->data[b + ch->sample->length];
2042 ch->sample_position += ch->step;
2043 if(ch->sample_position >= ch->sample->loop_end) {
2045 ch->sample_position = (ch->sample->loop_end << 1) - ch->sample_position;
2047 if(ch->sample_position >= ch->sample->length) {
2049 ch->sample_position -= ch->sample->length - 1;
2052 if(mod->linear_interpolation) {
2055 u_left = (b == 1 || b - 2 <= ch->sample->loop_start) ? ch->sample->data[(
uint32_t)ch->sample_position] : ch->sample->data[b - 2];
2056 if (ch->sample->stereo) {
2057 u_right = (b == 1 || b - 2 <= ch->sample->loop_start) ? ch->sample->data[(
uint32_t)ch->sample_position + ch->sample->length] : ch->sample->data[b + ch->sample->length - 2];
2062 ch->sample_position -= ch->step;
2063 if(ch->sample_position <= ch->sample->loop_start) {
2065 ch->sample_position = (ch->sample->loop_start << 1) - ch->sample_position;
2067 if (ch->sample_position <= .0f) {
2069 ch->sample_position = .0f;
2080 float endval_left = mod->linear_interpolation ? jar_xm_LERP(u_left, v_left, t) : u_left;
2081 float endval_right = mod->linear_interpolation ? jar_xm_LERP(u_right, v_right, t) : u_right;
2084 if(ch->frame_count < jar_xm_SAMPLE_RAMPING_POINTS) {
2086 if (previous > -1) {
2087 ch->end_of_previous_sample_left[previous] = jar_xm_LERP(ch->end_of_previous_sample_left[ch->frame_count], endval_left, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
2088 ch->end_of_previous_sample_right[previous] = jar_xm_LERP(ch->end_of_previous_sample_right[ch->frame_count], endval_right, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
2090 ch->curr_left = jar_xm_LERP(ch->end_of_previous_sample_left[ch->frame_count], endval_left, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
2091 ch->curr_right = jar_xm_LERP(ch->end_of_previous_sample_right[ch->frame_count], endval_right, (
float)ch->frame_count / (
float)jar_xm_SAMPLE_RAMPING_POINTS);
2096 if (previous > -1) {
2097 ch->end_of_previous_sample_left[previous] = endval_left;
2098 ch->end_of_previous_sample_right[previous] = endval_right;
2100 ch->curr_left = endval_left;
2101 ch->curr_right = endval_right;
2106static void jar_xm_mixdown(
jar_xm_context_t* ctx,
float* left,
float* right) {
2107 jar_xm_module_t* mod = &(ctx->module);
2109 if(ctx->remaining_samples_in_tick <= 0) {
2112 ctx->remaining_samples_in_tick--;
2115 if(ctx->max_loop_count > 0 && ctx->loop_count > ctx->max_loop_count) {
return; }
2117 for(
uint8_t i = 0; i < ctx->module.num_channels; ++i) {
2118 jar_xm_channel_context_t* ch = ctx->channels + i;
2119 if(ch->instrument !=
NULL && ch->sample !=
NULL && ch->sample_position >= 0) {
2120 jar_xm_next_of_sample(ctx, ch, -1);
2121 if(!ch->muted && !ch->instrument->muted) {
2122 *left += ch->curr_left * ch->actual_volume * (1.f - ch->actual_panning);
2123 *right += ch->curr_right * ch->actual_volume * ch->actual_panning;
2128 jar_xm_SLIDE_TOWARDS(ch->actual_volume, ch->target_volume, ctx->volume_ramp);
2129 jar_xm_SLIDE_TOWARDS(ch->actual_panning, ch->target_panning, ctx->panning_ramp);
2133 if (ctx->global_volume != 1.0f) {
2134 *left *= ctx->global_volume;
2135 *right *= ctx->global_volume;
2144 if(*left < -1.0) {*left = -1.0;}
else if(*left > 1.0) {*left = 1.0;};
2145 if(*right < -1.0) {*right = -1.0;}
else if(*right > 1.0) {*right = 1.0;};
2150 ctx->generated_samples += numsamples;
2151 for(
size_t i = 0; i < numsamples; i++) {
2152 jar_xm_mixdown(ctx, output + (2 * i), output + (2 * i + 1));
2162 total += ctx->remaining_samples_in_tick;
2163 ctx->remaining_samples_in_tick = 0;
2166 ctx->loop_count = currentLoopCount;
2174#define DEBUG(...) do { \
2175 fprintf(stderr, __VA_ARGS__); \
2179#define DEBUG_ERR(...) do { \
2180 fprintf(stderr, __VA_ARGS__); \
2184#define FATAL(...) do { \
2185 fprintf(stderr, __VA_ARGS__); \
2190#define FATAL_ERR(...) do { \
2191 fprintf(stderr, __VA_ARGS__); \
2202 xmf = fopen(filename,
"rb");
2204 DEBUG_ERR(
"Could not open input file");
2209 fseek(xmf, 0, SEEK_END);
2214 DEBUG_ERR(
"fseek() failed");
2220 if(!data || fread(data, 1, size, xmf) < size) {
2222 DEBUG_ERR(data ?
"fread() failed" :
"JARXM_MALLOC() failed");
2236 case 1: DEBUG(
"could not create context: module is not sane\n");
2240 case 2: FATAL(
"could not create context: malloc failed\n");
2243 default: FATAL(
"could not create context: unknown error\n");
2254 jar_xm_cut_note(&ctx->channels[i]);
2256 ctx->generated_samples = 0;
2257 ctx->current_row = 0;
2258 ctx->current_table_index = 0;
2259 ctx->current_tick = 0;
2260 ctx->tempo =ctx->default_tempo;
2261 ctx->bpm = ctx->default_bpm;
2262 ctx->global_volume = ctx->default_global_volume;
2267 if (ctx->module.linear_interpolation) {
2268 ctx->module.linear_interpolation = 0;
2270 ctx->module.linear_interpolation = 1;
2276 jar_xm_cut_note(&ctx->channels[i]);
2278 ctx->current_row = 0;
2279 ctx->current_tick = 0;
2281 ctx->current_table_index = table_ptr;
2282 ctx->module.restart_position = table_ptr;
2284 ctx->current_table_index = 0;
2285 ctx->module.restart_position = 0;
2286 ctx->tempo =ctx->default_tempo;
2287 ctx->bpm = ctx->default_bpm;
2288 ctx->global_volume = ctx->default_global_volume;
2294const char* xm_note_chr(
int number) {
2295 if (number == NOTE_OFF) {
2298 number = number % 12;
2300 case 1:
return "C-";
2301 case 2:
return "C#";
2302 case 3:
return "D-";
2303 case 4:
return "D#";
2304 case 5:
return "E-";
2305 case 6:
return "F-";
2306 case 7:
return "F#";
2307 case 8:
return "G-";
2308 case 9:
return "G#";
2309 case 10:
return "A-";
2310 case 11:
return "A#";
2311 case 12:
return "B-";
2316const char* xm_octave_chr(
int number) {
2317 if (number == NOTE_OFF) {
2321 int number2 = number - number % 12;
2322 int result = floor(number2 / 12) + 1;
2332 default:
return "?";
2338const char* xm_effect_chr(
int fx) {
2350 case 0xA:
return "A";
2351 case 0xB:
return "B";
2352 case 0xC:
return "C";
2353 case 0xD:
return "D";
2354 case 0xE:
return "E";
2355 case 0xF:
return "F";
2356 case 16:
return "G";
2357 case 17:
return "H";
2358 case 21:
return "L";
2359 case 25:
return "P";
2360 case 27:
return "R";
2361 case 29:
return "T";
2362 case 33:
return "X";
2363 default:
return "?";
2377 y += size;
DrawText(
TextFormat(
"CUR PAT = %i", ctx->module.pattern_table[ctx->current_table_index]), x, y, size,
WHITE);
2386 x = size * 12; y = 0;
2398 for (
int i=0; i < ctx->module.length; i++) {
2399 if (i == ctx->jump_dest) {
2400 if (ctx->position_jump) {
2406 if (i == ctx->current_table_index) {
2417 jar_xm_pattern_t* cur = ctx->module.patterns + ctx->module.pattern_table[ctx->current_table_index];
2422 for(
uint8_t i = 0; i < ctx->module.num_channels; i++) {
2431 for (
int j=(ctx->current_row - 14); j<(ctx->current_row + 15); j++) {
2434 if (j >=0 && j < (cur->num_rows)) {
2438 for(
uint8_t i = 0; i < ctx->module.num_channels; i++) {
2439 if (j==(ctx->current_row)) {
2444 jar_xm_pattern_slot_t *s = cur->slots + j * ctx->module.num_channels + i;
2446 if (s->note > 0) {
DrawText(
TextFormat(
"%s%s", xm_note_chr(s->note), xm_octave_chr(s->note) ), x, y, size,
WHITE);}
else {
DrawText(
"...", x, y, size,
GRAY);};
2447 if (s->instrument > 0) {
2449 if (s->volume_column == 0) {
2454 if (s->volume_column == 0) {
2458 if (s->volume_column > 0) {
DrawText(
TextFormat(
"%02X", (s->volume_column - 16)), x + size * 4, y, size,
WHITE);};
2459 if (s->effect_type > 0 || s->effect_param > 0) {
DrawText(
TextFormat(
"%s%02X", xm_effect_chr(s->effect_type), s->effect_param), x + size * 6, y, size,
WHITE);};
uint16_t jar_xm_get_module_length(jar_xm_context_t *)
uint16_t jar_xm_get_number_of_rows(jar_xm_context_t *ctx, uint16_t)
uint64_t jar_xm_get_latest_trigger_of_instrument(jar_xm_context_t *ctx, uint16_t)
void jar_xm_set_max_loop_count(jar_xm_context_t *ctx, uint8_t loopcnt)
uint16_t jar_xm_get_number_of_samples(jar_xm_context_t *ctx, uint16_t)
uint16_t jar_xm_get_number_of_instruments(jar_xm_context_t *ctx)
void jar_xm_free_context(jar_xm_context_t *ctx)
void jar_xm_get_position(jar_xm_context_t *ctx, uint8_t *pattern_index, uint8_t *pattern, uint8_t *row, uint64_t *samples)
int jar_xm_create_context(jar_xm_context_t **ctx, const char *moddata, uint32_t rate)
const char * jar_xm_get_module_name(jar_xm_context_t *ctx)
void jar_xm_generate_samples(jar_xm_context_t *ctx, float *output, size_t numsamples)
bool jar_xm_mute_channel(jar_xm_context_t *ctx, uint16_t, bool)
uint16_t jar_xm_get_number_of_patterns(jar_xm_context_t *ctx)
bool jar_xm_mute_instrument(jar_xm_context_t *ctx, uint16_t, bool)
uint8_t jar_xm_get_loop_count(jar_xm_context_t *ctx)
void jar_xm_generate_samples_16bit(jar_xm_context_t *ctx, short *output, size_t numsamples)
uint64_t jar_xm_get_latest_trigger_of_sample(jar_xm_context_t *ctx, uint16_t instr, uint16_t sample)
const char * jar_xm_get_tracker_name(jar_xm_context_t *ctx)
void jar_xm_get_playing_speed(jar_xm_context_t *ctx, uint16_t *bpm, uint16_t *tempo)
int jar_xm_create_context_safe(jar_xm_context_t **ctx, const char *moddata, size_t moddata_length, uint32_t rate)
void jar_xm_generate_samples_8bit(jar_xm_context_t *ctx, char *output, size_t numsamples)
uint64_t jar_xm_get_latest_trigger_of_channel(jar_xm_context_t *ctx, uint16_t)
uint16_t jar_xm_get_number_of_channels(jar_xm_context_t *ctx)
uint64_t jar_xm_get_remaining_samples(jar_xm_context_t *ctx)
struct jar_xm_context_s jar_xm_context_t
int jar_xm_create_context_from_file(jar_xm_context_t **ctx, uint32_t rate, const char *filename)
RLAPI const char * TextFormat(const char *text,...)
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color)
unsigned __int64 uint64_t