Logo

index : raylib-jai

---

  • summary
  • about
  • tree
  • log
  • branches
<< path: root/public/raylib-jai.git/html/Raylib/raylib/src/external/jar_mod.h blob: 7ecf9f437aee90d908643d7959b8e529e2046d40 [raw] [clear marker]

        
0// jar_mod.h - v0.01 - public domain C0 - Joshua Reisenauer
1//
2// HISTORY:
3//
4// v0.01 2016-03-12 Setup
5//
6//
7// USAGE:
8//
9// In ONE source file, put:
10//
11// #define JAR_MOD_IMPLEMENTATION
12// #include "jar_mod.h"
13//
14// Other source files should just include jar_mod.h
15//
16// SAMPLE CODE:
17// jar_mod_context_t modctx;
18// short samplebuff[4096];
19// bool bufferFull = false;
20// int intro_load(void)
21// {
22// jar_mod_init(&modctx);
23// jar_mod_load_file(&modctx, "file.mod");
24// return 1;
25// }
26// int intro_unload(void)
27// {
28// jar_mod_unload(&modctx);
29// return 1;
30// }
31// int intro_tick(long counter)
32// {
33// if(!bufferFull)
34// {
35// jar_mod_fillbuffer(&modctx, samplebuff, 4096, 0);
36// bufferFull=true;
37// }
38// if(IsKeyDown(KEY_ENTER))
39// return 1;
40// return 0;
41// }
42//
43//
44// LISCENSE:
45//
46// Written by: Jean-François DEL NERO (http://hxc2001.com/) <Email : jeanfrancoisdelnero <> free.fr>
47// Adapted to jar_mod by: Joshua Adam Reisenauer <kd7tck@gmail.com>
48// This program is free software. It comes without any warranty, to the
49// extent permitted by applicable law. You can redistribute it and/or
50// modify it under the terms of the Do What The Fuck You Want To Public
51// License, Version 2, as published by Sam Hocevar. See
52// http://sam.zoy.org/wtfpl/COPYING for more details.
53///////////////////////////////////////////////////////////////////////////////////
54// HxCMOD Core API:
55// -------------------------------------------
56// int jar_mod_init(jar_mod_context_t * modctx)
57//
58// - Initialize the jar_mod_context_t buffer. Must be called before doing anything else.
59// Return 1 if success. 0 in case of error.
60// -------------------------------------------
61// mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
62//
63// - "Load" a MOD from file, context must already be initialized.
64// Return size of file in bytes.
65// -------------------------------------------
66// void jar_mod_fillbuffer( jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf )
67//
68// - Generate and return the next samples chunk to outbuffer.
69// nbsample specify the number of stereo 16bits samples you want.
70// The output format is by default signed 48000Hz 16-bit Stereo PCM samples, otherwise it is changed with jar_mod_setcfg().
71// The output buffer size in bytes must be equal to ( nbsample * 2 * channels ).
72// The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused.
73// -------------------------------------------
74// void jar_mod_unload( jar_mod_context_t * modctx )
75// - "Unload" / clear the player status.
76// -------------------------------------------
77///////////////////////////////////////////////////////////////////////////////////
78
79
80#ifndef INCLUDE_JAR_MOD_H
81#define INCLUDE_JAR_MOD_H
82
83// Allow custom memory allocators
84#ifndef JARMOD_MALLOC
85 #define JARMOD_MALLOC(sz) malloc(sz)
86#endif
87#ifndef JARMOD_FREE
88 #define JARMOD_FREE(p) free(p)
89#endif
90
91
92// Basic type
93typedef unsigned char muchar;
94typedef unsigned short muint;
95typedef short mint;
96typedef unsigned long mulong;
97
98#define NUMMAXCHANNELS 32
99#define MAXNOTES 12*12
100#define DEFAULT_SAMPLE_RATE 48000
101//
102// MOD file structures
103//
104
105#pragma pack(1)
106
107typedef struct {
108 muchar name[22];
109 muint length;
110 muchar finetune;
111 muchar volume;
112 muint reppnt;
113 muint replen;
114} sample;
115
116typedef struct {
117 muchar sampperiod;
118 muchar period;
119 muchar sampeffect;
120 muchar effect;
121} note;
122
123typedef struct {
124 muchar title[20];
125 sample samples[31];
126 muchar length; // length of tablepos
127 muchar protracker;
128 muchar patterntable[128];
129 muchar signature[4];
130 muchar speed;
131} module;
132
133#pragma pack()
134
135//
136// HxCMod Internal structures
137//
138typedef struct {
139 char* sampdata;
140 muint sampnum;
141 muint length;
142 muint reppnt;
143 muint replen;
144 mulong samppos;
145 muint period;
146 muchar volume;
147 mulong ticks;
148 muchar effect;
149 muchar parameffect;
150 muint effect_code;
151 mint decalperiod;
152 mint portaspeed;
153 mint portaperiod;
154 mint vibraperiod;
155 mint Arpperiods[3];
156 muchar ArpIndex;
157 mint oldk;
158 muchar volumeslide;
159 muchar vibraparam;
160 muchar vibrapointeur;
161 muchar finetune;
162 muchar cut_param;
163 muint patternloopcnt;
164 muint patternloopstartpoint;
165} channel;
166
167typedef struct {
168 module song;
169 char* sampledata[31];
170 note* patterndata[128];
171
172 mulong playrate;
173 muint tablepos;
174 muint patternpos;
175 muint patterndelay;
176 muint jump_loop_effect;
177 muchar bpm;
178 mulong patternticks;
179 mulong patterntickse;
180 mulong patternticksaim;
181 mulong sampleticksconst;
182 mulong samplenb;
183 channel channels[NUMMAXCHANNELS];
184 muint number_of_channels;
185 muint fullperiod[MAXNOTES * 8];
186 muint mod_loaded;
187 mint last_r_sample;
188 mint last_l_sample;
189 mint stereo;
190 mint stereo_separation;
191 mint bits;
192 mint filter;
193
194 muchar *modfile; // the raw mod file
195 mulong modfilesize;
196 muint loopcount;
197} jar_mod_context_t;
198
199//
200// Player states structures
201//
202typedef struct track_state_
203{
204 unsigned char instrument_number;
205 unsigned short cur_period;
206 unsigned char cur_volume;
207 unsigned short cur_effect;
208 unsigned short cur_parameffect;
209}track_state;
210
211typedef struct tracker_state_
212{
213 int number_of_tracks;
214 int bpm;
215 int speed;
216 int cur_pattern;
217 int cur_pattern_pos;
218 int cur_pattern_table_pos;
219 unsigned int buf_index;
220 track_state tracks[32];
221}tracker_state;
222
223typedef struct tracker_state_instrument_
224{
225 char name[22];
226 int active;
227}tracker_state_instrument;
228
229typedef struct jar_mod_tracker_buffer_state_
230{
231 int nb_max_of_state;
232 int nb_of_state;
233 int cur_rd_index;
234 int sample_step;
235 char name[64];
236 tracker_state_instrument instruments[31];
237 tracker_state * track_state_buf;
238}jar_mod_tracker_buffer_state;
239
240#ifdef __cplusplus
241extern "C" {
242#endif
243
244bool jar_mod_init(jar_mod_context_t * modctx);
245bool jar_mod_setcfg(jar_mod_context_t * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter);
246void jar_mod_fillbuffer(jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf);
247void jar_mod_unload(jar_mod_context_t * modctx);
248mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename);
249mulong jar_mod_current_samples(jar_mod_context_t * modctx);
250mulong jar_mod_max_samples(jar_mod_context_t * modctx);
251void jar_mod_seek_start(jar_mod_context_t * ctx);
252
253#ifdef __cplusplus
254}
255#endif
256//--------------------------------------------------------------------
257
258
259
260//-------------------------------------------------------------------------------
261#ifdef JAR_MOD_IMPLEMENTATION
262
263#include <stdio.h>
264#include <stdlib.h>
265//#include <stdbool.h>
266
267// Effects list
268#define EFFECT_ARPEGGIO 0x0 // Supported
269#define EFFECT_PORTAMENTO_UP 0x1 // Supported
270#define EFFECT_PORTAMENTO_DOWN 0x2 // Supported
271#define EFFECT_TONE_PORTAMENTO 0x3 // Supported
272#define EFFECT_VIBRATO 0x4 // Supported
273#define EFFECT_VOLSLIDE_TONEPORTA 0x5 // Supported
274#define EFFECT_VOLSLIDE_VIBRATO 0x6 // Supported
275#define EFFECT_VOLSLIDE_TREMOLO 0x7 // - TO BE DONE -
276#define EFFECT_SET_PANNING 0x8 // - TO BE DONE -
277#define EFFECT_SET_OFFSET 0x9 // Supported
278#define EFFECT_VOLUME_SLIDE 0xA // Supported
279#define EFFECT_JUMP_POSITION 0xB // Supported
280#define EFFECT_SET_VOLUME 0xC // Supported
281#define EFFECT_PATTERN_BREAK 0xD // Supported
282
283#define EFFECT_EXTENDED 0xE
284#define EFFECT_E_FINE_PORTA_UP 0x1 // Supported
285#define EFFECT_E_FINE_PORTA_DOWN 0x2 // Supported
286#define EFFECT_E_GLISSANDO_CTRL 0x3 // - TO BE DONE -
287#define EFFECT_E_VIBRATO_WAVEFORM 0x4 // - TO BE DONE -
288#define EFFECT_E_SET_FINETUNE 0x5 // - TO BE DONE -
289#define EFFECT_E_PATTERN_LOOP 0x6 // Supported
290#define EFFECT_E_TREMOLO_WAVEFORM 0x7 // - TO BE DONE -
291#define EFFECT_E_SET_PANNING_2 0x8 // - TO BE DONE -
292#define EFFECT_E_RETRIGGER_NOTE 0x9 // - TO BE DONE -
293#define EFFECT_E_FINE_VOLSLIDE_UP 0xA // Supported
294#define EFFECT_E_FINE_VOLSLIDE_DOWN 0xB // Supported
295#define EFFECT_E_NOTE_CUT 0xC // Supported
296#define EFFECT_E_NOTE_DELAY 0xD // - TO BE DONE -
297#define EFFECT_E_PATTERN_DELAY 0xE // Supported
298#define EFFECT_E_INVERT_LOOP 0xF // - TO BE DONE -
299#define EFFECT_SET_SPEED 0xF0 // Supported
300#define EFFECT_SET_TEMPO 0xF2 // Supported
301
302#define PERIOD_TABLE_LENGTH MAXNOTES
303#define FULL_PERIOD_TABLE_LENGTH ( PERIOD_TABLE_LENGTH * 8 )
304
305static const short periodtable[]=
306{
307 27392, 25856, 24384, 23040, 21696, 20480, 19328, 18240, 17216, 16256, 15360, 14496,
308 13696, 12928, 12192, 11520, 10848, 10240, 9664, 9120, 8606, 8128, 7680, 7248,
309 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624,
310 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1812,
311 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906,
312 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
313 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
314 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
315 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
316 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28,
317 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14,
318 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7
319};
320
321static const short sintable[]={
322 0, 24, 49, 74, 97, 120, 141,161,
323 180, 197, 212, 224, 235, 244, 250,253,
324 255, 253, 250, 244, 235, 224, 212,197,
325 180, 161, 141, 120, 97, 74, 49, 24
326};
327
328typedef struct modtype_
329{
330 unsigned char signature[5];
331 int numberofchannels;
332}modtype;
333
334modtype modlist[]=
335{
336 { "M!K!",4},
337 { "M.K.",4},
338 { "FLT4",4},
339 { "FLT8",8},
340 { "4CHN",4},
341 { "6CHN",6},
342 { "8CHN",8},
343 { "10CH",10},
344 { "12CH",12},
345 { "14CH",14},
346 { "16CH",16},
347 { "18CH",18},
348 { "20CH",20},
349 { "22CH",22},
350 { "24CH",24},
351 { "26CH",26},
352 { "28CH",28},
353 { "30CH",30},
354 { "32CH",32},
355 { "",0}
356};
357
358///////////////////////////////////////////////////////////////////////////////////
359
360static void memcopy( void * dest, void *source, unsigned long size )
361{
362 unsigned long i;
363 unsigned char * d,*s;
364
365 d=(unsigned char*)dest;
366 s=(unsigned char*)source;
367 for(i=0;i<size;i++)
368 {
369 d[i]=s[i];
370 }
371}
372
373static void memclear( void * dest, unsigned char value, unsigned long size )
374{
375 unsigned long i;
376 unsigned char * d;
377
378 d=(unsigned char*)dest;
379 for(i=0;i<size;i++)
380 {
381 d[i]=value;
382 }
383}
384
385static int memcompare( unsigned char * buf1, unsigned char * buf2, unsigned int size )
386{
387 unsigned int i;
388
389 i = 0;
390
391 while(i<size)
392 {
393 if(buf1[i] != buf2[i])
394 {
395 return 0;
396 }
397 i++;
398 }
399
400 return 1;
401}
402
403static int getnote( jar_mod_context_t * mod, unsigned short period, int finetune )
404{
405 int i;
406
407 for(i = 0; i < FULL_PERIOD_TABLE_LENGTH; i++)
408 {
409 if(period >= mod->fullperiod[i])
410 {
411 return i;
412 }
413 }
414
415 return MAXNOTES;
416}
417
418static void worknote( note * nptr, channel * cptr, char t, jar_mod_context_t * mod )
419{
420 muint sample, period, effect, operiod;
421 muint curnote, arpnote;
422
423 sample = (nptr->sampperiod & 0xF0) | (nptr->sampeffect >> 4);
424 period = ((nptr->sampperiod & 0xF) << 8) | nptr->period;
425 effect = ((nptr->sampeffect & 0xF) << 8) | nptr->effect;
426
427 operiod = cptr->period;
428
429 if ( period || sample )
430 {
431 if( sample && sample < 32 )
432 {
433 cptr->sampnum = sample - 1;
434 }
435
436 if( period || sample )
437 {
438 cptr->sampdata = (char *) mod->sampledata[cptr->sampnum];
439 cptr->length = mod->song.samples[cptr->sampnum].length;
440 cptr->reppnt = mod->song.samples[cptr->sampnum].reppnt;
441 cptr->replen = mod->song.samples[cptr->sampnum].replen;
442
443 cptr->finetune = (mod->song.samples[cptr->sampnum].finetune)&0xF;
444
445 if(effect>>8!=4 && effect>>8!=6)
446 {
447 cptr->vibraperiod=0;
448 cptr->vibrapointeur=0;
449 }
450 }
451
452 if( (sample != 0) && ( (effect>>8) != EFFECT_VOLSLIDE_TONEPORTA ) )
453 {
454 cptr->volume = mod->song.samples[cptr->sampnum].volume;
455 cptr->volumeslide = 0;
456 }
457
458 if( ( (effect>>8) != EFFECT_TONE_PORTAMENTO && (effect>>8)!=EFFECT_VOLSLIDE_TONEPORTA) )
459 {
460 if (period!=0)
461 cptr->samppos = 0;
462 }
463
464 cptr->decalperiod = 0;
465 if( period )
466 {
467 if(cptr->finetune)
468 {
469 if( cptr->finetune <= 7 )
470 {
471 period = mod->fullperiod[getnote(mod,period,0) + cptr->finetune];
472 }
473 else
474 {
475 period = mod->fullperiod[getnote(mod,period,0) - (16 - (cptr->finetune)) ];
476 }
477 }
478
479 cptr->period = period;
480 }
481
482 }
483
484 cptr->effect = 0;
485 cptr->parameffect = 0;
486 cptr->effect_code = effect;
487
488 switch (effect >> 8)
489 {
490 case EFFECT_ARPEGGIO:
491 /*
492 [0]: Arpeggio
493 Where [0][x][y] means "play note, note+x semitones, note+y
494 semitones, then return to original note". The fluctuations are
495 carried out evenly spaced in one pattern division. They are usually
496 used to simulate chords, but this doesn't work too well. They are
497 also used to produce heavy vibrato. A major chord is when x=4, y=7.
498 A minor chord is when x=3, y=7.
499 */
500
501 if(effect&0xff)
502 {
503 cptr->effect = EFFECT_ARPEGGIO;
504 cptr->parameffect = effect&0xff;
505
506 cptr->ArpIndex = 0;
507
508 curnote = getnote(mod,cptr->period,cptr->finetune);
509
510 cptr->Arpperiods[0] = cptr->period;
511
512 arpnote = curnote + (((cptr->parameffect>>4)&0xF)*8);
513 if( arpnote >= FULL_PERIOD_TABLE_LENGTH )
514 arpnote = FULL_PERIOD_TABLE_LENGTH - 1;
515
516 cptr->Arpperiods[1] = mod->fullperiod[arpnote];
517
518 arpnote = curnote + (((cptr->parameffect)&0xF)*8);
519 if( arpnote >= FULL_PERIOD_TABLE_LENGTH )
520 arpnote = FULL_PERIOD_TABLE_LENGTH - 1;
521
522 cptr->Arpperiods[2] = mod->fullperiod[arpnote];
523 }
524 break;
525
526 case EFFECT_PORTAMENTO_UP:
527 /*
528 [1]: Slide up
529 Where [1][x][y] means "smoothly decrease the period of current
530 sample by x*16+y after each tick in the division". The
531 ticks/division are set with the 'set speed' effect (see below). If
532 the period of the note being played is z, then the final period
533 will be z - (x*16 + y)*(ticks - 1). As the slide rate depends on
534 the speed, changing the speed will change the slide. You cannot
535 slide beyond the note B3 (period 113).
536 */
537
538 cptr->effect = EFFECT_PORTAMENTO_UP;
539 cptr->parameffect = effect&0xff;
540 break;
541
542 case EFFECT_PORTAMENTO_DOWN:
543 /*
544 [2]: Slide down
545 Where [2][x][y] means "smoothly increase the period of current
546 sample by x*16+y after each tick in the division". Similar to [1],
547 but lowers the pitch. You cannot slide beyond the note C1 (period
548 856).
549 */
550
551 cptr->effect = EFFECT_PORTAMENTO_DOWN;
552 cptr->parameffect = effect&0xff;
553 break;
554
555 case EFFECT_TONE_PORTAMENTO:
556 /*
557 [3]: Slide to note
558 Where [3][x][y] means "smoothly change the period of current sample
559 by x*16+y after each tick in the division, never sliding beyond
560 current period". The period-length in this channel's division is a
561 parameter to this effect, and hence is not played. Sliding to a
562 note is similar to effects [1] and [2], but the slide will not go
563 beyond the given period, and the direction is implied by that
564 period. If x and y are both 0, then the old slide will continue.
565 */
566
567 cptr->effect = EFFECT_TONE_PORTAMENTO;
568 if( (effect&0xff) != 0 )
569 {
570 cptr->portaspeed = (short)(effect&0xff);
571 }
572
573 if(period!=0)
574 {
575 cptr->portaperiod = period;
576 cptr->period = operiod;
577 }
578 break;
579
580 case EFFECT_VIBRATO:
581 /*
582 [4]: Vibrato
583 Where [4][x][y] means "oscillate the sample pitch using a
584 particular waveform with amplitude y/16 semitones, such that (x *
585 ticks)/64 cycles occur in the division". The waveform is set using
586 effect [14][4]. By placing vibrato effects on consecutive
587 divisions, the vibrato effect can be maintained. If either x or y
588 are 0, then the old vibrato values will be used.
589 */
590
591 cptr->effect = EFFECT_VIBRATO;
592 if( ( effect & 0x0F ) != 0 ) // Depth continue or change ?
593 cptr->vibraparam = (cptr->vibraparam & 0xF0) | ( effect & 0x0F );
594 if( ( effect & 0xF0 ) != 0 ) // Speed continue or change ?
595 cptr->vibraparam = (cptr->vibraparam & 0x0F) | ( effect & 0xF0 );
596
597 break;
598
599 case EFFECT_VOLSLIDE_TONEPORTA:
600 /*
601 [5]: Continue 'Slide to note', but also do Volume slide
602 Where [5][x][y] means "either slide the volume up x*(ticks - 1) or
603 slide the volume down y*(ticks - 1), at the same time as continuing
604 the last 'Slide to note'". It is illegal for both x and y to be
605 non-zero. You cannot slide outside the volume range 0..64. The
606 period-length in this channel's division is a parameter to this
607 effect, and hence is not played.
608 */
609
610 if( period != 0 )
611 {
612 cptr->portaperiod = period;
613 cptr->period = operiod;
614 }
615
616 cptr->effect = EFFECT_VOLSLIDE_TONEPORTA;
617 if( ( effect & 0xFF ) != 0 )
618 cptr->volumeslide = ( effect & 0xFF );
619
620 break;
621
622 case EFFECT_VOLSLIDE_VIBRATO:
623 /*
624 [6]: Continue 'Vibrato', but also do Volume slide
625 Where [6][x][y] means "either slide the volume up x*(ticks - 1) or
626 slide the volume down y*(ticks - 1), at the same time as continuing
627 the last 'Vibrato'". It is illegal for both x and y to be non-zero.
628 You cannot slide outside the volume range 0..64.
629 */
630
631 cptr->effect = EFFECT_VOLSLIDE_VIBRATO;
632 if( (effect & 0xFF) != 0 )
633 cptr->volumeslide = (effect & 0xFF);
634 break;
635
636 case EFFECT_SET_OFFSET:
637 /*
638 [9]: Set sample offset
639 Where [9][x][y] means "play the sample from offset x*4096 + y*256".
640 The offset is measured in words. If no sample is given, yet one is
641 still playing on this channel, it should be retriggered to the new
642 offset using the current volume.
643 */
644
645 cptr->samppos = ((effect>>4) * 4096) + ((effect&0xF)*256);
646
647 break;
648
649 case EFFECT_VOLUME_SLIDE:
650 /*
651 [10]: Volume slide
652 Where [10][x][y] means "either slide the volume up x*(ticks - 1) or
653 slide the volume down y*(ticks - 1)". If both x and y are non-zero,
654 then the y value is ignored (assumed to be 0). You cannot slide
655 outside the volume range 0..64.
656 */
657
658 cptr->effect = EFFECT_VOLUME_SLIDE;
659 cptr->volumeslide = (effect & 0xFF);
660 break;
661
662 case EFFECT_JUMP_POSITION:
663 /*
664 [11]: Position Jump
665 Where [11][x][y] means "stop the pattern after this division, and
666 continue the song at song-position x*16+y". This shifts the
667 'pattern-cursor' in the pattern table (see above). Legal values for
668 x*16+y are from 0 to 127.
669 */
670
671 mod->tablepos = (effect & 0xFF);
672 if(mod->tablepos >= mod->song.length)
673 {
674 mod->tablepos = 0;
675 }
676 mod->patternpos = 0;
677 mod->jump_loop_effect = 1;
678
679 break;
680
681 case EFFECT_SET_VOLUME:
682 /*
683 [12]: Set volume
684 Where [12][x][y] means "set current sample's volume to x*16+y".
685 Legal volumes are 0..64.
686 */
687
688 cptr->volume = (effect & 0xFF);
689 break;
690
691 case EFFECT_PATTERN_BREAK:
692 /*
693 [13]: Pattern Break
694 Where [13][x][y] means "stop the pattern after this division, and
695 continue the song at the next pattern at division x*10+y" (the 10
696 is not a typo). Legal divisions are from 0 to 63 (note Protracker
697 exception above).
698 */
699
700 mod->patternpos = ( ((effect>>4)&0xF)*10 + (effect&0xF) ) * mod->number_of_channels;
701 mod->jump_loop_effect = 1;
702 mod->tablepos++;
703 if(mod->tablepos >= mod->song.length)
704 {
705 mod->tablepos = 0;
706 }
707
708 break;
709
710 case EFFECT_EXTENDED:
711 switch( (effect>>4) & 0xF )
712 {
713 case EFFECT_E_FINE_PORTA_UP:
714 /*
715 [14][1]: Fineslide up
716 Where [14][1][x] means "decrement the period of the current sample
717 by x". The incrementing takes place at the beginning of the
718 division, and hence there is no actual sliding. You cannot slide
719 beyond the note B3 (period 113).
720 */
721
722 cptr->period -= (effect & 0xF);
723 if( cptr->period < 113 )
724 cptr->period = 113;
725 break;
726
727 case EFFECT_E_FINE_PORTA_DOWN:
728 /*
729 [14][2]: Fineslide down
730 Where [14][2][x] means "increment the period of the current sample
731 by x". Similar to [14][1] but shifts the pitch down. You cannot
732 slide beyond the note C1 (period 856).
733 */
734
735 cptr->period += (effect & 0xF);
736 if( cptr->period > 856 )
737 cptr->period = 856;
738 break;
739
740 case EFFECT_E_FINE_VOLSLIDE_UP:
741 /*
742 [14][10]: Fine volume slide up
743 Where [14][10][x] means "increment the volume of the current sample
744 by x". The incrementing takes place at the beginning of the
745 division, and hence there is no sliding. You cannot slide beyond
746 volume 64.
747 */
748
749 cptr->volume += (effect & 0xF);
750 if( cptr->volume>64 )
751 cptr->volume = 64;
752 break;
753
754 case EFFECT_E_FINE_VOLSLIDE_DOWN:
755 /*
756 [14][11]: Fine volume slide down
757 Where [14][11][x] means "decrement the volume of the current sample
758 by x". Similar to [14][10] but lowers volume. You cannot slide
759 beyond volume 0.
760 */
761
762 cptr->volume -= (effect & 0xF);
763 if( cptr->volume > 200 )
764 cptr->volume = 0;
765 break;
766
767 case EFFECT_E_PATTERN_LOOP:
768 /*
769 [14][6]: Loop pattern
770 Where [14][6][x] means "set the start of a loop to this division if
771 x is 0, otherwise after this division, jump back to the start of a
772 loop and play it another x times before continuing". If the start
773 of the loop was not set, it will default to the start of the
774 current pattern. Hence 'loop pattern' cannot be performed across
775 multiple patterns. Note that loops do not support nesting, and you
776 may generate an infinite loop if you try to nest 'loop pattern's.
777 */
778
779 if( effect & 0xF )
780 {
781 if( cptr->patternloopcnt )
782 {
783 cptr->patternloopcnt--;
784 if( cptr->patternloopcnt )
785 {
786 mod->patternpos = cptr->patternloopstartpoint;
787 mod->jump_loop_effect = 1;
788 }
789 else
790 {
791 cptr->patternloopstartpoint = mod->patternpos ;
792 }
793 }
794 else
795 {
796 cptr->patternloopcnt = (effect & 0xF);
797 mod->patternpos = cptr->patternloopstartpoint;
798 mod->jump_loop_effect = 1;
799 }
800 }
801 else // Start point
802 {
803 cptr->patternloopstartpoint = mod->patternpos;
804 }
805
806 break;
807
808 case EFFECT_E_PATTERN_DELAY:
809 /*
810 [14][14]: Delay pattern
811 Where [14][14][x] means "after this division there will be a delay
812 equivalent to the time taken to play x divisions after which the
813 pattern will be resumed". The delay only relates to the
814 interpreting of new divisions, and all effects and previous notes
815 continue during delay.
816 */
817
818 mod->patterndelay = (effect & 0xF);
819 break;
820
821 case EFFECT_E_NOTE_CUT:
822 /*
823 [14][12]: Cut sample
824 Where [14][12][x] means "after the current sample has been played
825 for x ticks in this division, its volume will be set to 0". This
826 implies that if x is 0, then you will not hear any of the sample.
827 If you wish to insert "silence" in a pattern, it is better to use a
828 "silence"-sample (see above) due to the lack of proper support for
829 this effect.
830 */
831 cptr->effect = EFFECT_E_NOTE_CUT;
832 cptr->cut_param = (effect & 0xF);
833 if(!cptr->cut_param)
834 cptr->volume = 0;
835 break;
836
837 default:
838
839 break;
840 }
841 break;
842
843 case 0xF:
844 /*
845 [15]: Set speed
846 Where [15][x][y] means "set speed to x*16+y". Though it is nowhere
847 near that simple. Let z = x*16+y. Depending on what values z takes,
848 different units of speed are set, there being two: ticks/division
849 and beats/minute (though this one is only a label and not strictly
850 true). If z=0, then what should technically happen is that the
851 module stops, but in practice it is treated as if z=1, because
852 there is already a method for stopping the module (running out of
853 patterns). If z<=32, then it means "set ticks/division to z"
854 otherwise it means "set beats/minute to z" (convention says that
855 this should read "If z<32.." but there are some composers out there
856 that defy conventions). Default values are 6 ticks/division, and
857 125 beats/minute (4 divisions = 1 beat). The beats/minute tag is
858 only meaningful for 6 ticks/division. To get a more accurate view
859 of how things work, use the following formula:
860 24 * beats/minute
861 divisions/minute = -----------------
862 ticks/division
863 Hence divisions/minute range from 24.75 to 6120, eg. to get a value
864 of 2000 divisions/minute use 3 ticks/division and 250 beats/minute.
865 If multiple "set speed" effects are performed in a single division,
866 the ones on higher-numbered channels take precedence over the ones
867 on lower-numbered channels. This effect has a large number of
868 different implementations, but the one described here has the
869 widest usage.
870 */
871
872 if( (effect&0xFF) < 0x21 )
873 {
874 if( effect&0xFF )
875 {
876 mod->song.speed = effect&0xFF;
877 mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm)));
878 }
879 }
880
881 if( (effect&0xFF) >= 0x21 )
882 {
883 /// HZ = 2 * BPM / 5
884 mod->bpm = effect&0xFF;
885 mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm)));
886 }
887
888 break;
889
890 default:
891 // Unsupported effect
892 break;
893
894 }
895
896}
897
898static void workeffect( note * nptr, channel * cptr )
899{
900 switch(cptr->effect)
901 {
902 case EFFECT_ARPEGGIO:
903
904 if( cptr->parameffect )
905 {
906 cptr->decalperiod = cptr->period - cptr->Arpperiods[cptr->ArpIndex];
907
908 cptr->ArpIndex++;
909 if( cptr->ArpIndex>2 )
910 cptr->ArpIndex = 0;
911 }
912 break;
913
914 case EFFECT_PORTAMENTO_UP:
915
916 if(cptr->period)
917 {
918 cptr->period -= cptr->parameffect;
919
920 if( cptr->period < 113 || cptr->period > 20000 )
921 cptr->period = 113;
922 }
923
924 break;
925
926 case EFFECT_PORTAMENTO_DOWN:
927
928 if(cptr->period)
929 {
930 cptr->period += cptr->parameffect;
931
932 if( cptr->period > 20000 )
933 cptr->period = 20000;
934 }
935
936 break;
937
938 case EFFECT_VOLSLIDE_TONEPORTA:
939 case EFFECT_TONE_PORTAMENTO:
940
941 if( cptr->period && ( cptr->period != cptr->portaperiod ) && cptr->portaperiod )
942 {
943 if( cptr->period > cptr->portaperiod )
944 {
945 if( cptr->period - cptr->portaperiod >= cptr->portaspeed )
946 {
947 cptr->period -= cptr->portaspeed;
948 }
949 else
950 {
951 cptr->period = cptr->portaperiod;
952 }
953 }
954 else
955 {
956 if( cptr->portaperiod - cptr->period >= cptr->portaspeed )
957 {
958 cptr->period += cptr->portaspeed;
959 }
960 else
961 {
962 cptr->period = cptr->portaperiod;
963 }
964 }
965
966 if( cptr->period == cptr->portaperiod )
967 {
968 // If the slide is over, don't let it to be retriggered.
969 cptr->portaperiod = 0;
970 }
971 }
972
973 if( cptr->effect == EFFECT_VOLSLIDE_TONEPORTA )
974 {
975 if( cptr->volumeslide > 0x0F )
976 {
977 cptr->volume = cptr->volume + (cptr->volumeslide>>4);
978
979 if(cptr->volume>63)
980 cptr->volume = 63;
981 }
982 else
983 {
984 cptr->volume = cptr->volume - (cptr->volumeslide);
985
986 if(cptr->volume>63)
987 cptr->volume=0;
988 }
989 }
990 break;
991
992 case EFFECT_VOLSLIDE_VIBRATO:
993 case EFFECT_VIBRATO:
994
995 cptr->vibraperiod = ( (cptr->vibraparam&0xF) * sintable[cptr->vibrapointeur&0x1F] )>>7;
996
997 if( cptr->vibrapointeur > 31 )
998 cptr->vibraperiod = -cptr->vibraperiod;
999
1000 cptr->vibrapointeur = (cptr->vibrapointeur+(((cptr->vibraparam>>4))&0xf)) & 0x3F;
1001
1002 if( cptr->effect == EFFECT_VOLSLIDE_VIBRATO )
1003 {
1004 if( cptr->volumeslide > 0xF )
1005 {
1006 cptr->volume = cptr->volume+(cptr->volumeslide>>4);
1007
1008 if( cptr->volume > 64 )
1009 cptr->volume = 64;
1010 }
1011 else
1012 {
1013 cptr->volume = cptr->volume - cptr->volumeslide;
1014
1015 if( cptr->volume > 64 )
1016 cptr->volume = 0;
1017 }
1018 }
1019
1020 break;
1021
1022 case EFFECT_VOLUME_SLIDE:
1023
1024 if( cptr->volumeslide > 0xF )
1025 {
1026 cptr->volume += (cptr->volumeslide>>4);
1027
1028 if( cptr->volume > 64 )
1029 cptr->volume = 64;
1030 }
1031 else
1032 {
1033 cptr->volume -= (cptr->volumeslide&0xf);
1034
1035 if( cptr->volume > 64 )
1036 cptr->volume = 0;
1037 }
1038 break;
1039
1040 case EFFECT_E_NOTE_CUT:
1041 if(cptr->cut_param)
1042 cptr->cut_param--;
1043
1044 if(!cptr->cut_param)
1045 cptr->volume = 0;
1046 break;
1047
1048 default:
1049 break;
1050
1051 }
1052
1053}
1054
1055///////////////////////////////////////////////////////////////////////////////////
1056bool jar_mod_init(jar_mod_context_t * modctx)
1057{
1058 muint i,j;
1059
1060 if( modctx )
1061 {
1062 memclear(modctx, 0, sizeof(jar_mod_context_t));
1063 modctx->playrate = DEFAULT_SAMPLE_RATE;
1064 modctx->stereo = 1;
1065 modctx->stereo_separation = 1;
1066 modctx->bits = 16;
1067 modctx->filter = 1;
1068
1069 for(i=0; i < PERIOD_TABLE_LENGTH - 1; i++)
1070 {
1071 for(j=0; j < 8; j++)
1072 {
1073 modctx->fullperiod[(i*8) + j] = periodtable[i] - ((( periodtable[i] - periodtable[i+1] ) / 8) * j);
1074 }
1075 }
1076
1077 return 1;
1078 }
1079
1080 return 0;
1081}
1082
1083bool jar_mod_setcfg(jar_mod_context_t * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter)
1084{
1085 if( modctx )
1086 {
1087 modctx->playrate = samplerate;
1088
1089 if( stereo )
1090 modctx->stereo = 1;
1091 else
1092 modctx->stereo = 0;
1093
1094 if(stereo_separation < 4)
1095 {
1096 modctx->stereo_separation = stereo_separation;
1097 }
1098
1099 if( bits == 8 || bits == 16 )
1100 modctx->bits = bits;
1101 else
1102 modctx->bits = 16;
1103
1104 if( filter )
1105 modctx->filter = 1;
1106 else
1107 modctx->filter = 0;
1108
1109 return 1;
1110 }
1111
1112 return 0;
1113}
1114
1115// make certain that mod_data stays in memory while playing
1116static bool jar_mod_load( jar_mod_context_t * modctx, void * mod_data, int mod_data_size )
1117{
1118 muint i, max;
1119 unsigned short t;
1120 sample *sptr;
1121 unsigned char * modmemory,* endmodmemory;
1122
1123 modmemory = (unsigned char *)mod_data;
1124 endmodmemory = modmemory + mod_data_size;
1125
1126
1127
1128 if(modmemory)
1129 {
1130 if( modctx )
1131 {
1132 memcopy(&(modctx->song), modmemory, 1084);
1133
1134 i = 0;
1135 modctx->number_of_channels = 0;
1136 while(modlist[i].numberofchannels)
1137 {
1138 if(memcompare(modctx->song.signature,modlist[i].signature,4))
1139 {
1140 modctx->number_of_channels = modlist[i].numberofchannels;
1141 }
1142
1143 i++;
1144 }
1145
1146 if( !modctx->number_of_channels )
1147 {
1148 // 15 Samples modules support
1149 // Shift the whole datas to make it look likes a standard 4 channels mod.
1150 memcopy(&(modctx->song.signature), (void *)"M.K.", 4);
1151 memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130);
1152 memclear(&(modctx->song.samples[15]), 0, 480);
1153 modmemory += 600;
1154 modctx->number_of_channels = 4;
1155 }
1156 else
1157 {
1158 modmemory += 1084;
1159 }
1160
1161 if( modmemory >= endmodmemory )
1162 return 0; // End passed ? - Probably a bad file !
1163
1164 // Patterns loading
1165 for (i = max = 0; i < 128; i++)
1166 {
1167 while (max <= modctx->song.patterntable[i])
1168 {
1169 modctx->patterndata[max] = (note*)modmemory;
1170 modmemory += (256*modctx->number_of_channels);
1171 max++;
1172
1173 if( modmemory >= endmodmemory )
1174 return 0; // End passed ? - Probably a bad file !
1175 }
1176 }
1177
1178 for (i = 0; i < 31; i++)
1179 modctx->sampledata[i]=0;
1180
1181 // Samples loading
1182 for (i = 0, sptr = modctx->song.samples; i <31; i++, sptr++)
1183 {
1184 t= (sptr->length &0xFF00)>>8 | (sptr->length &0xFF)<<8;
1185 sptr->length = t*2;
1186
1187 t= (sptr->reppnt &0xFF00)>>8 | (sptr->reppnt &0xFF)<<8;
1188 sptr->reppnt = t*2;
1189
1190 t= (sptr->replen &0xFF00)>>8 | (sptr->replen &0xFF)<<8;
1191 sptr->replen = t*2;
1192
1193
1194 if (sptr->length == 0) continue;
1195
1196 modctx->sampledata[i] = (char*)modmemory;
1197 modmemory += sptr->length;
1198
1199 if (sptr->replen + sptr->reppnt > sptr->length)
1200 sptr->replen = sptr->length - sptr->reppnt;
1201
1202 if( modmemory > endmodmemory )
1203 return 0; // End passed ? - Probably a bad file !
1204 }
1205
1206 // States init
1207
1208 modctx->tablepos = 0;
1209 modctx->patternpos = 0;
1210 modctx->song.speed = 6;
1211 modctx->bpm = 125;
1212 modctx->samplenb = 0;
1213
1214 modctx->patternticks = (((long)modctx->song.speed * modctx->playrate * 5)/ (2 * modctx->bpm)) + 1;
1215 modctx->patternticksaim = ((long)modctx->song.speed * modctx->playrate * 5) / (2 * modctx->bpm);
1216
1217 modctx->sampleticksconst = 3546894UL / modctx->playrate; //8448*428/playrate;
1218
1219 for(i=0; i < modctx->number_of_channels; i++)
1220 {
1221 modctx->channels[i].volume = 0;
1222 modctx->channels[i].period = 0;
1223 }
1224
1225 modctx->mod_loaded = 1;
1226
1227 return 1;
1228 }
1229 }
1230
1231 return 0;
1232}
1233
1234void jar_mod_fillbuffer( jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf )
1235{
1236 unsigned long i, j;
1237 unsigned long k;
1238 unsigned char c;
1239 unsigned int state_remaining_steps;
1240 int l,r;
1241 int ll,lr;
1242 int tl,tr;
1243 short finalperiod;
1244 note *nptr;
1245 channel *cptr;
1246
1247 if( modctx && outbuffer )
1248 {
1249 if(modctx->mod_loaded)
1250 {
1251 state_remaining_steps = 0;
1252
1253 if( trkbuf )
1254 {
1255 trkbuf->cur_rd_index = 0;
1256
1257 memcopy(trkbuf->name,modctx->song.title,sizeof(modctx->song.title));
1258
1259 for(i=0;i<31;i++)
1260 {
1261 memcopy(trkbuf->instruments[i].name,modctx->song.samples[i].name,sizeof(trkbuf->instruments[i].name));
1262 }
1263 }
1264
1265 ll = modctx->last_l_sample;
1266 lr = modctx->last_r_sample;
1267
1268 for (i = 0; i < nbsample; i++)
1269 {
1270 //---------------------------------------
1271 if( modctx->patternticks++ > modctx->patternticksaim )
1272 {
1273 if( !modctx->patterndelay )
1274 {
1275 nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
1276 nptr = nptr + modctx->patternpos;
1277 cptr = modctx->channels;
1278
1279 modctx->patternticks = 0;
1280 modctx->patterntickse = 0;
1281
1282 for(c=0;c<modctx->number_of_channels;c++)
1283 {
1284 worknote((note*)(nptr+c), (channel*)(cptr+c),(char)(c+1),modctx);
1285 }
1286
1287 if( !modctx->jump_loop_effect )
1288 modctx->patternpos += modctx->number_of_channels;
1289 else
1290 modctx->jump_loop_effect = 0;
1291
1292 if( modctx->patternpos == 64*modctx->number_of_channels )
1293 {
1294 modctx->tablepos++;
1295 modctx->patternpos = 0;
1296 if(modctx->tablepos >= modctx->song.length)
1297 {
1298 modctx->tablepos = 0;
1299 modctx->loopcount++; // count next loop
1300 }
1301 }
1302 }
1303 else
1304 {
1305 modctx->patterndelay--;
1306 modctx->patternticks = 0;
1307 modctx->patterntickse = 0;
1308 }
1309
1310 }
1311
1312 if( modctx->patterntickse++ > (modctx->patternticksaim/modctx->song.speed) )
1313 {
1314 nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
1315 nptr = nptr + modctx->patternpos;
1316 cptr = modctx->channels;
1317
1318 for(c=0;c<modctx->number_of_channels;c++)
1319 {
1320 workeffect(nptr+c, cptr+c);
1321 }
1322
1323 modctx->patterntickse = 0;
1324 }
1325
1326 //---------------------------------------
1327
1328 if( trkbuf && !state_remaining_steps )
1329 {
1330 if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
1331 {
1332 memclear(&trkbuf->track_state_buf[trkbuf->nb_of_state], 0, sizeof(tracker_state));
1333 }
1334 }
1335
1336 l=0;
1337 r=0;
1338
1339 for(j =0, cptr = modctx->channels; j < modctx->number_of_channels ; j++, cptr++)
1340 {
1341 if( cptr->period != 0 )
1342 {
1343 finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod;
1344 if( finalperiod )
1345 {
1346 cptr->samppos += ( (modctx->sampleticksconst<<10) / finalperiod );
1347 }
1348
1349 cptr->ticks++;
1350
1351 if( cptr->replen<=2 )
1352 {
1353 if( (cptr->samppos>>10) >= (cptr->length) )
1354 {
1355 cptr->length = 0;
1356 cptr->reppnt = 0;
1357
1358 if( cptr->length )
1359 cptr->samppos = cptr->samppos % (((unsigned long)cptr->length)<<10);
1360 else
1361 cptr->samppos = 0;
1362 }
1363 }
1364 else
1365 {
1366 if( (cptr->samppos>>10) >= (unsigned long)(cptr->replen+cptr->reppnt) )
1367 {
1368 cptr->samppos = ((unsigned long)(cptr->reppnt)<<10) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<10));
1369 }
1370 }
1371
1372 k = cptr->samppos >> 10;
1373
1374 if( cptr->sampdata!=0 && ( ((j&3)==1) || ((j&3)==2) ) )
1375 {
1376 r += ( cptr->sampdata[k] * cptr->volume );
1377 }
1378
1379 if( cptr->sampdata!=0 && ( ((j&3)==0) || ((j&3)==3) ) )
1380 {
1381 l += ( cptr->sampdata[k] * cptr->volume );
1382 }
1383
1384 if( trkbuf && !state_remaining_steps )
1385 {
1386 if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
1387 {
1388 trkbuf->track_state_buf[trkbuf->nb_of_state].number_of_tracks = modctx->number_of_channels;
1389 trkbuf->track_state_buf[trkbuf->nb_of_state].buf_index = i;
1390 trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern = modctx->song.patterntable[modctx->tablepos];
1391 trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_pos = modctx->patternpos / modctx->number_of_channels;
1392 trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_table_pos = modctx->tablepos;
1393 trkbuf->track_state_buf[trkbuf->nb_of_state].bpm = modctx->bpm;
1394 trkbuf->track_state_buf[trkbuf->nb_of_state].speed = modctx->song.speed;
1395 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_effect = cptr->effect_code;
1396 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_parameffect = cptr->parameffect;
1397 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = finalperiod;
1398 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_volume = cptr->volume;
1399 trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].instrument_number = (unsigned char)cptr->sampnum;
1400 }
1401 }
1402 }
1403 }
1404
1405 if( trkbuf && !state_remaining_steps )
1406 {
1407 state_remaining_steps = trkbuf->sample_step;
1408
1409 if(trkbuf->nb_of_state < trkbuf->nb_max_of_state)
1410 trkbuf->nb_of_state++;
1411 }
1412 else
1413 {
1414 state_remaining_steps--;
1415 }
1416
1417 tl = (short)l;
1418 tr = (short)r;
1419
1420 if ( modctx->filter )
1421 {
1422 // Filter
1423 l = (l+ll)>>1;
1424 r = (r+lr)>>1;
1425 }
1426
1427 if ( modctx->stereo_separation == 1 )
1428 {
1429 // Left & Right Stereo panning
1430 l = (l+(r>>1));
1431 r = (r+(l>>1));
1432 }
1433
1434 // Level limitation
1435 if( l > 32767 ) l = 32767;
1436 if( l < -32768 ) l = -32768;
1437 if( r > 32767 ) r = 32767;
1438 if( r < -32768 ) r = -32768;
1439
1440 // Store the final sample.
1441 outbuffer[(i*2)] = l;
1442 outbuffer[(i*2)+1] = r;
1443
1444 ll = tl;
1445 lr = tr;
1446
1447 }
1448
1449 modctx->last_l_sample = ll;
1450 modctx->last_r_sample = lr;
1451
1452 modctx->samplenb = modctx->samplenb+nbsample;
1453 }
1454 else
1455 {
1456 for (i = 0; i < nbsample; i++)
1457 {
1458 // Mod not loaded. Return blank buffer.
1459 outbuffer[(i*2)] = 0;
1460 outbuffer[(i*2)+1] = 0;
1461 }
1462
1463 if(trkbuf)
1464 {
1465 trkbuf->nb_of_state = 0;
1466 trkbuf->cur_rd_index = 0;
1467 trkbuf->name[0] = 0;
1468 memclear(trkbuf->track_state_buf, 0, sizeof(tracker_state) * trkbuf->nb_max_of_state);
1469 memclear(trkbuf->instruments, 0, sizeof(trkbuf->instruments));
1470 }
1471 }
1472 }
1473}
1474
1475//resets internals for mod context
1476static bool jar_mod_reset( jar_mod_context_t * modctx)
1477{
1478 if(modctx)
1479 {
1480 memclear(&modctx->song, 0, sizeof(modctx->song));
1481 memclear(&modctx->sampledata, 0, sizeof(modctx->sampledata));
1482 memclear(&modctx->patterndata, 0, sizeof(modctx->patterndata));
1483 modctx->tablepos = 0;
1484 modctx->patternpos = 0;
1485 modctx->patterndelay = 0;
1486 modctx->jump_loop_effect = 0;
1487 modctx->bpm = 0;
1488 modctx->patternticks = 0;
1489 modctx->patterntickse = 0;
1490 modctx->patternticksaim = 0;
1491 modctx->sampleticksconst = 0;
1492 modctx->samplenb = 0;
1493 memclear(modctx->channels, 0, sizeof(modctx->channels));
1494 modctx->number_of_channels = 0;
1495 modctx->mod_loaded = 0;
1496 modctx->last_r_sample = 0;
1497 modctx->last_l_sample = 0;
1498
1499 return jar_mod_init(modctx);
1500 }
1501 return 0;
1502}
1503
1504void jar_mod_unload( jar_mod_context_t * modctx)
1505{
1506 if(modctx)
1507 {
1508 if(modctx->modfile)
1509 {
1510 JARMOD_FREE(modctx->modfile);
1511 modctx->modfile = 0;
1512 modctx->modfilesize = 0;
1513 modctx->loopcount = 0;
1514 }
1515 jar_mod_reset(modctx);
1516 }
1517}
1518
1519mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
1520{
1521 mulong fsize = 0;
1522 if(modctx->modfile)
1523 {
1524 JARMOD_FREE(modctx->modfile);
1525 modctx->modfile = 0;
1526 }
1527
1528 FILE *f = fopen(filename, "rb");
1529 if(f)
1530 {
1531 fseek(f,0,SEEK_END);
1532 fsize = ftell(f);
1533 fseek(f,0,SEEK_SET);
1534
1535 if(fsize && fsize < 32*1024*1024)
1536 {
1537 modctx->modfile = (muchar *) JARMOD_MALLOC(fsize);
1538 modctx->modfilesize = fsize;
1539 memset(modctx->modfile, 0, fsize);
1540 fread(modctx->modfile, fsize, 1, f);
1541 fclose(f);
1542
1543 if(!jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
1544 } else fsize = 0;
1545 }
1546 return fsize;
1547}
1548
1549mulong jar_mod_current_samples(jar_mod_context_t * modctx)
1550{
1551 if(modctx)
1552 return modctx->samplenb;
1553
1554 return 0;
1555}
1556
1557// Works, however it is very slow, this data should be cached to ensure it is run only once per file
1558mulong jar_mod_max_samples(jar_mod_context_t * ctx)
1559{
1560 mint buff[2];
1561 mulong len;
1562 mulong lastcount = ctx->loopcount;
1563
1564 while(ctx->loopcount <= lastcount)
1565 jar_mod_fillbuffer(ctx, buff, 1, 0);
1566
1567 len = ctx->samplenb;
1568 jar_mod_seek_start(ctx);
1569
1570 return len;
1571}
1572
1573// move seek_val to sample index, 0 -> jar_mod_max_samples is the range
1574void jar_mod_seek_start(jar_mod_context_t * ctx)
1575{
1576 if(ctx && ctx->modfile)
1577 {
1578 muchar* ftmp = ctx->modfile;
1579 mulong stmp = ctx->modfilesize;
1580 muint lcnt = ctx->loopcount;
1581
1582 if(jar_mod_reset(ctx)){
1583 jar_mod_load(ctx, ftmp, stmp);
1584 ctx->modfile = ftmp;
1585 ctx->modfilesize = stmp;
1586 ctx->loopcount = lcnt;
1587 }
1588 }
1589}
1590
1591#endif // end of JAR_MOD_IMPLEMENTATION
1592//-------------------------------------------------------------------------------
1593
1594
1595#endif //end of header file
1596
Copyright 2026  E766CB298A6D1E64 | Git-Thing heavily inspired by cgit