summaryrefslogtreecommitdiff
path: root/libs/raylib/src/external/jar_mod.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/raylib/src/external/jar_mod.h')
-rw-r--r--libs/raylib/src/external/jar_mod.h1596
1 files changed, 0 insertions, 1596 deletions
diff --git a/libs/raylib/src/external/jar_mod.h b/libs/raylib/src/external/jar_mod.h
deleted file mode 100644
index eacd3b7..0000000
--- a/libs/raylib/src/external/jar_mod.h
+++ /dev/null
@@ -1,1596 +0,0 @@
-// jar_mod.h - v0.01 - public domain C0 - Joshua Reisenauer
-//
-// HISTORY:
-//
-// v0.01 2016-03-12 Setup
-//
-//
-// USAGE:
-//
-// In ONE source file, put:
-//
-// #define JAR_MOD_IMPLEMENTATION
-// #include "jar_mod.h"
-//
-// Other source files should just include jar_mod.h
-//
-// SAMPLE CODE:
-// jar_mod_context_t modctx;
-// short samplebuff[4096];
-// bool bufferFull = false;
-// int intro_load(void)
-// {
-// jar_mod_init(&modctx);
-// jar_mod_load_file(&modctx, "file.mod");
-// return 1;
-// }
-// int intro_unload(void)
-// {
-// jar_mod_unload(&modctx);
-// return 1;
-// }
-// int intro_tick(long counter)
-// {
-// if(!bufferFull)
-// {
-// jar_mod_fillbuffer(&modctx, samplebuff, 4096, 0);
-// bufferFull=true;
-// }
-// if(IsKeyDown(KEY_ENTER))
-// return 1;
-// return 0;
-// }
-//
-//
-// LISCENSE:
-//
-// Written by: Jean-François DEL NERO (http://hxc2001.com/) <Email : jeanfrancoisdelnero <> free.fr>
-// Adapted to jar_mod by: Joshua Adam Reisenauer <kd7tck@gmail.com>
-// This program is free software. It comes without any warranty, to the
-// extent permitted by applicable law. You can redistribute it and/or
-// modify it under the terms of the Do What The Fuck You Want To Public
-// License, Version 2, as published by Sam Hocevar. See
-// http://sam.zoy.org/wtfpl/COPYING for more details.
-///////////////////////////////////////////////////////////////////////////////////
-// HxCMOD Core API:
-// -------------------------------------------
-// int jar_mod_init(jar_mod_context_t * modctx)
-//
-// - Initialize the jar_mod_context_t buffer. Must be called before doing anything else.
-// Return 1 if success. 0 in case of error.
-// -------------------------------------------
-// mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
-//
-// - "Load" a MOD from file, context must already be initialized.
-// Return size of file in bytes.
-// -------------------------------------------
-// void jar_mod_fillbuffer( jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf )
-//
-// - Generate and return the next samples chunk to outbuffer.
-// nbsample specify the number of stereo 16bits samples you want.
-// The output format is by default signed 48000Hz 16-bit Stereo PCM samples, otherwise it is changed with jar_mod_setcfg().
-// The output buffer size in bytes must be equal to ( nbsample * 2 * channels ).
-// The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused.
-// -------------------------------------------
-// void jar_mod_unload( jar_mod_context_t * modctx )
-// - "Unload" / clear the player status.
-// -------------------------------------------
-///////////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef INCLUDE_JAR_MOD_H
-#define INCLUDE_JAR_MOD_H
-
-// Allow custom memory allocators
-#ifndef JARMOD_MALLOC
- #define JARMOD_MALLOC(sz) malloc(sz)
-#endif
-#ifndef JARMOD_FREE
- #define JARMOD_FREE(p) free(p)
-#endif
-
-
-// Basic type
-typedef unsigned char muchar;
-typedef unsigned short muint;
-typedef short mint;
-typedef unsigned long mulong;
-
-#define NUMMAXCHANNELS 32
-#define MAXNOTES 12*12
-#define DEFAULT_SAMPLE_RATE 48000
-//
-// MOD file structures
-//
-
-#pragma pack(1)
-
-typedef struct {
- muchar name[22];
- muint length;
- muchar finetune;
- muchar volume;
- muint reppnt;
- muint replen;
-} sample;
-
-typedef struct {
- muchar sampperiod;
- muchar period;
- muchar sampeffect;
- muchar effect;
-} note;
-
-typedef struct {
- muchar title[20];
- sample samples[31];
- muchar length; // length of tablepos
- muchar protracker;
- muchar patterntable[128];
- muchar signature[4];
- muchar speed;
-} module;
-
-#pragma pack()
-
-//
-// HxCMod Internal structures
-//
-typedef struct {
- char* sampdata;
- muint sampnum;
- muint length;
- muint reppnt;
- muint replen;
- mulong samppos;
- muint period;
- muchar volume;
- mulong ticks;
- muchar effect;
- muchar parameffect;
- muint effect_code;
- mint decalperiod;
- mint portaspeed;
- mint portaperiod;
- mint vibraperiod;
- mint Arpperiods[3];
- muchar ArpIndex;
- mint oldk;
- muchar volumeslide;
- muchar vibraparam;
- muchar vibrapointeur;
- muchar finetune;
- muchar cut_param;
- muint patternloopcnt;
- muint patternloopstartpoint;
-} channel;
-
-typedef struct {
- module song;
- char* sampledata[31];
- note* patterndata[128];
-
- mulong playrate;
- muint tablepos;
- muint patternpos;
- muint patterndelay;
- muint jump_loop_effect;
- muchar bpm;
- mulong patternticks;
- mulong patterntickse;
- mulong patternticksaim;
- mulong sampleticksconst;
- mulong samplenb;
- channel channels[NUMMAXCHANNELS];
- muint number_of_channels;
- muint fullperiod[MAXNOTES * 8];
- muint mod_loaded;
- mint last_r_sample;
- mint last_l_sample;
- mint stereo;
- mint stereo_separation;
- mint bits;
- mint filter;
-
- muchar *modfile; // the raw mod file
- mulong modfilesize;
- muint loopcount;
-} jar_mod_context_t;
-
-//
-// Player states structures
-//
-typedef struct track_state_
-{
- unsigned char instrument_number;
- unsigned short cur_period;
- unsigned char cur_volume;
- unsigned short cur_effect;
- unsigned short cur_parameffect;
-}track_state;
-
-typedef struct tracker_state_
-{
- int number_of_tracks;
- int bpm;
- int speed;
- int cur_pattern;
- int cur_pattern_pos;
- int cur_pattern_table_pos;
- unsigned int buf_index;
- track_state tracks[32];
-}tracker_state;
-
-typedef struct tracker_state_instrument_
-{
- char name[22];
- int active;
-}tracker_state_instrument;
-
-typedef struct jar_mod_tracker_buffer_state_
-{
- int nb_max_of_state;
- int nb_of_state;
- int cur_rd_index;
- int sample_step;
- char name[64];
- tracker_state_instrument instruments[31];
- tracker_state * track_state_buf;
-}jar_mod_tracker_buffer_state;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool jar_mod_init(jar_mod_context_t * modctx);
-bool jar_mod_setcfg(jar_mod_context_t * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter);
-void jar_mod_fillbuffer(jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf);
-void jar_mod_unload(jar_mod_context_t * modctx);
-mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename);
-mulong jar_mod_current_samples(jar_mod_context_t * modctx);
-mulong jar_mod_max_samples(jar_mod_context_t * modctx);
-void jar_mod_seek_start(jar_mod_context_t * ctx);
-
-#ifdef __cplusplus
-}
-#endif
-//--------------------------------------------------------------------
-
-
-
-//-------------------------------------------------------------------------------
-#ifdef JAR_MOD_IMPLEMENTATION
-
-#include <stdio.h>
-#include <stdlib.h>
-//#include <stdbool.h>
-
-// Effects list
-#define EFFECT_ARPEGGIO 0x0 // Supported
-#define EFFECT_PORTAMENTO_UP 0x1 // Supported
-#define EFFECT_PORTAMENTO_DOWN 0x2 // Supported
-#define EFFECT_TONE_PORTAMENTO 0x3 // Supported
-#define EFFECT_VIBRATO 0x4 // Supported
-#define EFFECT_VOLSLIDE_TONEPORTA 0x5 // Supported
-#define EFFECT_VOLSLIDE_VIBRATO 0x6 // Supported
-#define EFFECT_VOLSLIDE_TREMOLO 0x7 // - TO BE DONE -
-#define EFFECT_SET_PANNING 0x8 // - TO BE DONE -
-#define EFFECT_SET_OFFSET 0x9 // Supported
-#define EFFECT_VOLUME_SLIDE 0xA // Supported
-#define EFFECT_JUMP_POSITION 0xB // Supported
-#define EFFECT_SET_VOLUME 0xC // Supported
-#define EFFECT_PATTERN_BREAK 0xD // Supported
-
-#define EFFECT_EXTENDED 0xE
-#define EFFECT_E_FINE_PORTA_UP 0x1 // Supported
-#define EFFECT_E_FINE_PORTA_DOWN 0x2 // Supported
-#define EFFECT_E_GLISSANDO_CTRL 0x3 // - TO BE DONE -
-#define EFFECT_E_VIBRATO_WAVEFORM 0x4 // - TO BE DONE -
-#define EFFECT_E_SET_FINETUNE 0x5 // - TO BE DONE -
-#define EFFECT_E_PATTERN_LOOP 0x6 // Supported
-#define EFFECT_E_TREMOLO_WAVEFORM 0x7 // - TO BE DONE -
-#define EFFECT_E_SET_PANNING_2 0x8 // - TO BE DONE -
-#define EFFECT_E_RETRIGGER_NOTE 0x9 // - TO BE DONE -
-#define EFFECT_E_FINE_VOLSLIDE_UP 0xA // Supported
-#define EFFECT_E_FINE_VOLSLIDE_DOWN 0xB // Supported
-#define EFFECT_E_NOTE_CUT 0xC // Supported
-#define EFFECT_E_NOTE_DELAY 0xD // - TO BE DONE -
-#define EFFECT_E_PATTERN_DELAY 0xE // Supported
-#define EFFECT_E_INVERT_LOOP 0xF // - TO BE DONE -
-#define EFFECT_SET_SPEED 0xF0 // Supported
-#define EFFECT_SET_TEMPO 0xF2 // Supported
-
-#define PERIOD_TABLE_LENGTH MAXNOTES
-#define FULL_PERIOD_TABLE_LENGTH ( PERIOD_TABLE_LENGTH * 8 )
-
-static const short periodtable[]=
-{
- 27392, 25856, 24384, 23040, 21696, 20480, 19328, 18240, 17216, 16256, 15360, 14496,
- 13696, 12928, 12192, 11520, 10848, 10240, 9664, 9120, 8606, 8128, 7680, 7248,
- 6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624,
- 3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1812,
- 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906,
- 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
- 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
- 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
- 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
- 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28,
- 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14,
- 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7
-};
-
-static const short sintable[]={
- 0, 24, 49, 74, 97, 120, 141,161,
- 180, 197, 212, 224, 235, 244, 250,253,
- 255, 253, 250, 244, 235, 224, 212,197,
- 180, 161, 141, 120, 97, 74, 49, 24
-};
-
-typedef struct modtype_
-{
- unsigned char signature[5];
- int numberofchannels;
-}modtype;
-
-modtype modlist[]=
-{
- { "M!K!",4},
- { "M.K.",4},
- { "FLT4",4},
- { "FLT8",8},
- { "4CHN",4},
- { "6CHN",6},
- { "8CHN",8},
- { "10CH",10},
- { "12CH",12},
- { "14CH",14},
- { "16CH",16},
- { "18CH",18},
- { "20CH",20},
- { "22CH",22},
- { "24CH",24},
- { "26CH",26},
- { "28CH",28},
- { "30CH",30},
- { "32CH",32},
- { "",0}
-};
-
-///////////////////////////////////////////////////////////////////////////////////
-
-static void memcopy( void * dest, void *source, unsigned long size )
-{
- unsigned long i;
- unsigned char * d,*s;
-
- d=(unsigned char*)dest;
- s=(unsigned char*)source;
- for(i=0;i<size;i++)
- {
- d[i]=s[i];
- }
-}
-
-static void memclear( void * dest, unsigned char value, unsigned long size )
-{
- unsigned long i;
- unsigned char * d;
-
- d=(unsigned char*)dest;
- for(i=0;i<size;i++)
- {
- d[i]=value;
- }
-}
-
-static int memcompare( unsigned char * buf1, unsigned char * buf2, unsigned int size )
-{
- unsigned int i;
-
- i = 0;
-
- while(i<size)
- {
- if(buf1[i] != buf2[i])
- {
- return 0;
- }
- i++;
- }
-
- return 1;
-}
-
-static int getnote( jar_mod_context_t * mod, unsigned short period, int finetune )
-{
- int i;
-
- for(i = 0; i < FULL_PERIOD_TABLE_LENGTH; i++)
- {
- if(period >= mod->fullperiod[i])
- {
- return i;
- }
- }
-
- return MAXNOTES;
-}
-
-static void worknote( note * nptr, channel * cptr, char t, jar_mod_context_t * mod )
-{
- muint sample, period, effect, operiod;
- muint curnote, arpnote;
-
- sample = (nptr->sampperiod & 0xF0) | (nptr->sampeffect >> 4);
- period = ((nptr->sampperiod & 0xF) << 8) | nptr->period;
- effect = ((nptr->sampeffect & 0xF) << 8) | nptr->effect;
-
- operiod = cptr->period;
-
- if ( period || sample )
- {
- if( sample && sample < 32 )
- {
- cptr->sampnum = sample - 1;
- }
-
- if( period || sample )
- {
- cptr->sampdata = (char *) mod->sampledata[cptr->sampnum];
- cptr->length = mod->song.samples[cptr->sampnum].length;
- cptr->reppnt = mod->song.samples[cptr->sampnum].reppnt;
- cptr->replen = mod->song.samples[cptr->sampnum].replen;
-
- cptr->finetune = (mod->song.samples[cptr->sampnum].finetune)&0xF;
-
- if(effect>>8!=4 && effect>>8!=6)
- {
- cptr->vibraperiod=0;
- cptr->vibrapointeur=0;
- }
- }
-
- if( (sample != 0) && ( (effect>>8) != EFFECT_VOLSLIDE_TONEPORTA ) )
- {
- cptr->volume = mod->song.samples[cptr->sampnum].volume;
- cptr->volumeslide = 0;
- }
-
- if( ( (effect>>8) != EFFECT_TONE_PORTAMENTO && (effect>>8)!=EFFECT_VOLSLIDE_TONEPORTA) )
- {
- if (period!=0)
- cptr->samppos = 0;
- }
-
- cptr->decalperiod = 0;
- if( period )
- {
- if(cptr->finetune)
- {
- if( cptr->finetune <= 7 )
- {
- period = mod->fullperiod[getnote(mod,period,0) + cptr->finetune];
- }
- else
- {
- period = mod->fullperiod[getnote(mod,period,0) - (16 - (cptr->finetune)) ];
- }
- }
-
- cptr->period = period;
- }
-
- }
-
- cptr->effect = 0;
- cptr->parameffect = 0;
- cptr->effect_code = effect;
-
- switch (effect >> 8)
- {
- case EFFECT_ARPEGGIO:
- /*
- [0]: Arpeggio
- Where [0][x][y] means "play note, note+x semitones, note+y
- semitones, then return to original note". The fluctuations are
- carried out evenly spaced in one pattern division. They are usually
- used to simulate chords, but this doesn't work too well. They are
- also used to produce heavy vibrato. A major chord is when x=4, y=7.
- A minor chord is when x=3, y=7.
- */
-
- if(effect&0xff)
- {
- cptr->effect = EFFECT_ARPEGGIO;
- cptr->parameffect = effect&0xff;
-
- cptr->ArpIndex = 0;
-
- curnote = getnote(mod,cptr->period,cptr->finetune);
-
- cptr->Arpperiods[0] = cptr->period;
-
- arpnote = curnote + (((cptr->parameffect>>4)&0xF)*8);
- if( arpnote >= FULL_PERIOD_TABLE_LENGTH )
- arpnote = FULL_PERIOD_TABLE_LENGTH - 1;
-
- cptr->Arpperiods[1] = mod->fullperiod[arpnote];
-
- arpnote = curnote + (((cptr->parameffect)&0xF)*8);
- if( arpnote >= FULL_PERIOD_TABLE_LENGTH )
- arpnote = FULL_PERIOD_TABLE_LENGTH - 1;
-
- cptr->Arpperiods[2] = mod->fullperiod[arpnote];
- }
- break;
-
- case EFFECT_PORTAMENTO_UP:
- /*
- [1]: Slide up
- Where [1][x][y] means "smoothly decrease the period of current
- sample by x*16+y after each tick in the division". The
- ticks/division are set with the 'set speed' effect (see below). If
- the period of the note being played is z, then the final period
- will be z - (x*16 + y)*(ticks - 1). As the slide rate depends on
- the speed, changing the speed will change the slide. You cannot
- slide beyond the note B3 (period 113).
- */
-
- cptr->effect = EFFECT_PORTAMENTO_UP;
- cptr->parameffect = effect&0xff;
- break;
-
- case EFFECT_PORTAMENTO_DOWN:
- /*
- [2]: Slide down
- Where [2][x][y] means "smoothly increase the period of current
- sample by x*16+y after each tick in the division". Similar to [1],
- but lowers the pitch. You cannot slide beyond the note C1 (period
- 856).
- */
-
- cptr->effect = EFFECT_PORTAMENTO_DOWN;
- cptr->parameffect = effect&0xff;
- break;
-
- case EFFECT_TONE_PORTAMENTO:
- /*
- [3]: Slide to note
- Where [3][x][y] means "smoothly change the period of current sample
- by x*16+y after each tick in the division, never sliding beyond
- current period". The period-length in this channel's division is a
- parameter to this effect, and hence is not played. Sliding to a
- note is similar to effects [1] and [2], but the slide will not go
- beyond the given period, and the direction is implied by that
- period. If x and y are both 0, then the old slide will continue.
- */
-
- cptr->effect = EFFECT_TONE_PORTAMENTO;
- if( (effect&0xff) != 0 )
- {
- cptr->portaspeed = (short)(effect&0xff);
- }
-
- if(period!=0)
- {
- cptr->portaperiod = period;
- cptr->period = operiod;
- }
- break;
-
- case EFFECT_VIBRATO:
- /*
- [4]: Vibrato
- Where [4][x][y] means "oscillate the sample pitch using a
- particular waveform with amplitude y/16 semitones, such that (x *
- ticks)/64 cycles occur in the division". The waveform is set using
- effect [14][4]. By placing vibrato effects on consecutive
- divisions, the vibrato effect can be maintained. If either x or y
- are 0, then the old vibrato values will be used.
- */
-
- cptr->effect = EFFECT_VIBRATO;
- if( ( effect & 0x0F ) != 0 ) // Depth continue or change ?
- cptr->vibraparam = (cptr->vibraparam & 0xF0) | ( effect & 0x0F );
- if( ( effect & 0xF0 ) != 0 ) // Speed continue or change ?
- cptr->vibraparam = (cptr->vibraparam & 0x0F) | ( effect & 0xF0 );
-
- break;
-
- case EFFECT_VOLSLIDE_TONEPORTA:
- /*
- [5]: Continue 'Slide to note', but also do Volume slide
- Where [5][x][y] means "either slide the volume up x*(ticks - 1) or
- slide the volume down y*(ticks - 1), at the same time as continuing
- the last 'Slide to note'". It is illegal for both x and y to be
- non-zero. You cannot slide outside the volume range 0..64. The
- period-length in this channel's division is a parameter to this
- effect, and hence is not played.
- */
-
- if( period != 0 )
- {
- cptr->portaperiod = period;
- cptr->period = operiod;
- }
-
- cptr->effect = EFFECT_VOLSLIDE_TONEPORTA;
- if( ( effect & 0xFF ) != 0 )
- cptr->volumeslide = ( effect & 0xFF );
-
- break;
-
- case EFFECT_VOLSLIDE_VIBRATO:
- /*
- [6]: Continue 'Vibrato', but also do Volume slide
- Where [6][x][y] means "either slide the volume up x*(ticks - 1) or
- slide the volume down y*(ticks - 1), at the same time as continuing
- the last 'Vibrato'". It is illegal for both x and y to be non-zero.
- You cannot slide outside the volume range 0..64.
- */
-
- cptr->effect = EFFECT_VOLSLIDE_VIBRATO;
- if( (effect & 0xFF) != 0 )
- cptr->volumeslide = (effect & 0xFF);
- break;
-
- case EFFECT_SET_OFFSET:
- /*
- [9]: Set sample offset
- Where [9][x][y] means "play the sample from offset x*4096 + y*256".
- The offset is measured in words. If no sample is given, yet one is
- still playing on this channel, it should be retriggered to the new
- offset using the current volume.
- */
-
- cptr->samppos = ((effect>>4) * 4096) + ((effect&0xF)*256);
-
- break;
-
- case EFFECT_VOLUME_SLIDE:
- /*
- [10]: Volume slide
- Where [10][x][y] means "either slide the volume up x*(ticks - 1) or
- slide the volume down y*(ticks - 1)". If both x and y are non-zero,
- then the y value is ignored (assumed to be 0). You cannot slide
- outside the volume range 0..64.
- */
-
- cptr->effect = EFFECT_VOLUME_SLIDE;
- cptr->volumeslide = (effect & 0xFF);
- break;
-
- case EFFECT_JUMP_POSITION:
- /*
- [11]: Position Jump
- Where [11][x][y] means "stop the pattern after this division, and
- continue the song at song-position x*16+y". This shifts the
- 'pattern-cursor' in the pattern table (see above). Legal values for
- x*16+y are from 0 to 127.
- */
-
- mod->tablepos = (effect & 0xFF);
- if(mod->tablepos >= mod->song.length)
- {
- mod->tablepos = 0;
- }
- mod->patternpos = 0;
- mod->jump_loop_effect = 1;
-
- break;
-
- case EFFECT_SET_VOLUME:
- /*
- [12]: Set volume
- Where [12][x][y] means "set current sample's volume to x*16+y".
- Legal volumes are 0..64.
- */
-
- cptr->volume = (effect & 0xFF);
- break;
-
- case EFFECT_PATTERN_BREAK:
- /*
- [13]: Pattern Break
- Where [13][x][y] means "stop the pattern after this division, and
- continue the song at the next pattern at division x*10+y" (the 10
- is not a typo). Legal divisions are from 0 to 63 (note Protracker
- exception above).
- */
-
- mod->patternpos = ( ((effect>>4)&0xF)*10 + (effect&0xF) ) * mod->number_of_channels;
- mod->jump_loop_effect = 1;
- mod->tablepos++;
- if(mod->tablepos >= mod->song.length)
- {
- mod->tablepos = 0;
- }
-
- break;
-
- case EFFECT_EXTENDED:
- switch( (effect>>4) & 0xF )
- {
- case EFFECT_E_FINE_PORTA_UP:
- /*
- [14][1]: Fineslide up
- Where [14][1][x] means "decrement the period of the current sample
- by x". The incrementing takes place at the beginning of the
- division, and hence there is no actual sliding. You cannot slide
- beyond the note B3 (period 113).
- */
-
- cptr->period -= (effect & 0xF);
- if( cptr->period < 113 )
- cptr->period = 113;
- break;
-
- case EFFECT_E_FINE_PORTA_DOWN:
- /*
- [14][2]: Fineslide down
- Where [14][2][x] means "increment the period of the current sample
- by x". Similar to [14][1] but shifts the pitch down. You cannot
- slide beyond the note C1 (period 856).
- */
-
- cptr->period += (effect & 0xF);
- if( cptr->period > 856 )
- cptr->period = 856;
- break;
-
- case EFFECT_E_FINE_VOLSLIDE_UP:
- /*
- [14][10]: Fine volume slide up
- Where [14][10][x] means "increment the volume of the current sample
- by x". The incrementing takes place at the beginning of the
- division, and hence there is no sliding. You cannot slide beyond
- volume 64.
- */
-
- cptr->volume += (effect & 0xF);
- if( cptr->volume>64 )
- cptr->volume = 64;
- break;
-
- case EFFECT_E_FINE_VOLSLIDE_DOWN:
- /*
- [14][11]: Fine volume slide down
- Where [14][11][x] means "decrement the volume of the current sample
- by x". Similar to [14][10] but lowers volume. You cannot slide
- beyond volume 0.
- */
-
- cptr->volume -= (effect & 0xF);
- if( cptr->volume > 200 )
- cptr->volume = 0;
- break;
-
- case EFFECT_E_PATTERN_LOOP:
- /*
- [14][6]: Loop pattern
- Where [14][6][x] means "set the start of a loop to this division if
- x is 0, otherwise after this division, jump back to the start of a
- loop and play it another x times before continuing". If the start
- of the loop was not set, it will default to the start of the
- current pattern. Hence 'loop pattern' cannot be performed across
- multiple patterns. Note that loops do not support nesting, and you
- may generate an infinite loop if you try to nest 'loop pattern's.
- */
-
- if( effect & 0xF )
- {
- if( cptr->patternloopcnt )
- {
- cptr->patternloopcnt--;
- if( cptr->patternloopcnt )
- {
- mod->patternpos = cptr->patternloopstartpoint;
- mod->jump_loop_effect = 1;
- }
- else
- {
- cptr->patternloopstartpoint = mod->patternpos ;
- }
- }
- else
- {
- cptr->patternloopcnt = (effect & 0xF);
- mod->patternpos = cptr->patternloopstartpoint;
- mod->jump_loop_effect = 1;
- }
- }
- else // Start point
- {
- cptr->patternloopstartpoint = mod->patternpos;
- }
-
- break;
-
- case EFFECT_E_PATTERN_DELAY:
- /*
- [14][14]: Delay pattern
- Where [14][14][x] means "after this division there will be a delay
- equivalent to the time taken to play x divisions after which the
- pattern will be resumed". The delay only relates to the
- interpreting of new divisions, and all effects and previous notes
- continue during delay.
- */
-
- mod->patterndelay = (effect & 0xF);
- break;
-
- case EFFECT_E_NOTE_CUT:
- /*
- [14][12]: Cut sample
- Where [14][12][x] means "after the current sample has been played
- for x ticks in this division, its volume will be set to 0". This
- implies that if x is 0, then you will not hear any of the sample.
- If you wish to insert "silence" in a pattern, it is better to use a
- "silence"-sample (see above) due to the lack of proper support for
- this effect.
- */
- cptr->effect = EFFECT_E_NOTE_CUT;
- cptr->cut_param = (effect & 0xF);
- if(!cptr->cut_param)
- cptr->volume = 0;
- break;
-
- default:
-
- break;
- }
- break;
-
- case 0xF:
- /*
- [15]: Set speed
- Where [15][x][y] means "set speed to x*16+y". Though it is nowhere
- near that simple. Let z = x*16+y. Depending on what values z takes,
- different units of speed are set, there being two: ticks/division
- and beats/minute (though this one is only a label and not strictly
- true). If z=0, then what should technically happen is that the
- module stops, but in practice it is treated as if z=1, because
- there is already a method for stopping the module (running out of
- patterns). If z<=32, then it means "set ticks/division to z"
- otherwise it means "set beats/minute to z" (convention says that
- this should read "If z<32.." but there are some composers out there
- that defy conventions). Default values are 6 ticks/division, and
- 125 beats/minute (4 divisions = 1 beat). The beats/minute tag is
- only meaningful for 6 ticks/division. To get a more accurate view
- of how things work, use the following formula:
- 24 * beats/minute
- divisions/minute = -----------------
- ticks/division
- Hence divisions/minute range from 24.75 to 6120, eg. to get a value
- of 2000 divisions/minute use 3 ticks/division and 250 beats/minute.
- If multiple "set speed" effects are performed in a single division,
- the ones on higher-numbered channels take precedence over the ones
- on lower-numbered channels. This effect has a large number of
- different implementations, but the one described here has the
- widest usage.
- */
-
- if( (effect&0xFF) < 0x21 )
- {
- if( effect&0xFF )
- {
- mod->song.speed = effect&0xFF;
- mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm)));
- }
- }
-
- if( (effect&0xFF) >= 0x21 )
- {
- /// HZ = 2 * BPM / 5
- mod->bpm = effect&0xFF;
- mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm)));
- }
-
- break;
-
- default:
- // Unsupported effect
- break;
-
- }
-
-}
-
-static void workeffect( note * nptr, channel * cptr )
-{
- switch(cptr->effect)
- {
- case EFFECT_ARPEGGIO:
-
- if( cptr->parameffect )
- {
- cptr->decalperiod = cptr->period - cptr->Arpperiods[cptr->ArpIndex];
-
- cptr->ArpIndex++;
- if( cptr->ArpIndex>2 )
- cptr->ArpIndex = 0;
- }
- break;
-
- case EFFECT_PORTAMENTO_UP:
-
- if(cptr->period)
- {
- cptr->period -= cptr->parameffect;
-
- if( cptr->period < 113 || cptr->period > 20000 )
- cptr->period = 113;
- }
-
- break;
-
- case EFFECT_PORTAMENTO_DOWN:
-
- if(cptr->period)
- {
- cptr->period += cptr->parameffect;
-
- if( cptr->period > 20000 )
- cptr->period = 20000;
- }
-
- break;
-
- case EFFECT_VOLSLIDE_TONEPORTA:
- case EFFECT_TONE_PORTAMENTO:
-
- if( cptr->period && ( cptr->period != cptr->portaperiod ) && cptr->portaperiod )
- {
- if( cptr->period > cptr->portaperiod )
- {
- if( cptr->period - cptr->portaperiod >= cptr->portaspeed )
- {
- cptr->period -= cptr->portaspeed;
- }
- else
- {
- cptr->period = cptr->portaperiod;
- }
- }
- else
- {
- if( cptr->portaperiod - cptr->period >= cptr->portaspeed )
- {
- cptr->period += cptr->portaspeed;
- }
- else
- {
- cptr->period = cptr->portaperiod;
- }
- }
-
- if( cptr->period == cptr->portaperiod )
- {
- // If the slide is over, don't let it to be retriggered.
- cptr->portaperiod = 0;
- }
- }
-
- if( cptr->effect == EFFECT_VOLSLIDE_TONEPORTA )
- {
- if( cptr->volumeslide > 0x0F )
- {
- cptr->volume = cptr->volume + (cptr->volumeslide>>4);
-
- if(cptr->volume>63)
- cptr->volume = 63;
- }
- else
- {
- cptr->volume = cptr->volume - (cptr->volumeslide);
-
- if(cptr->volume>63)
- cptr->volume=0;
- }
- }
- break;
-
- case EFFECT_VOLSLIDE_VIBRATO:
- case EFFECT_VIBRATO:
-
- cptr->vibraperiod = ( (cptr->vibraparam&0xF) * sintable[cptr->vibrapointeur&0x1F] )>>7;
-
- if( cptr->vibrapointeur > 31 )
- cptr->vibraperiod = -cptr->vibraperiod;
-
- cptr->vibrapointeur = (cptr->vibrapointeur+(((cptr->vibraparam>>4))&0xf)) & 0x3F;
-
- if( cptr->effect == EFFECT_VOLSLIDE_VIBRATO )
- {
- if( cptr->volumeslide > 0xF )
- {
- cptr->volume = cptr->volume+(cptr->volumeslide>>4);
-
- if( cptr->volume > 64 )
- cptr->volume = 64;
- }
- else
- {
- cptr->volume = cptr->volume - cptr->volumeslide;
-
- if( cptr->volume > 64 )
- cptr->volume = 0;
- }
- }
-
- break;
-
- case EFFECT_VOLUME_SLIDE:
-
- if( cptr->volumeslide > 0xF )
- {
- cptr->volume += (cptr->volumeslide>>4);
-
- if( cptr->volume > 64 )
- cptr->volume = 64;
- }
- else
- {
- cptr->volume -= (cptr->volumeslide&0xf);
-
- if( cptr->volume > 64 )
- cptr->volume = 0;
- }
- break;
-
- case EFFECT_E_NOTE_CUT:
- if(cptr->cut_param)
- cptr->cut_param--;
-
- if(!cptr->cut_param)
- cptr->volume = 0;
- break;
-
- default:
- break;
-
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-bool jar_mod_init(jar_mod_context_t * modctx)
-{
- muint i,j;
-
- if( modctx )
- {
- memclear(modctx, 0, sizeof(jar_mod_context_t));
- modctx->playrate = DEFAULT_SAMPLE_RATE;
- modctx->stereo = 1;
- modctx->stereo_separation = 1;
- modctx->bits = 16;
- modctx->filter = 1;
-
- for(i=0; i < PERIOD_TABLE_LENGTH - 1; i++)
- {
- for(j=0; j < 8; j++)
- {
- modctx->fullperiod[(i*8) + j] = periodtable[i] - ((( periodtable[i] - periodtable[i+1] ) / 8) * j);
- }
- }
-
- return 1;
- }
-
- return 0;
-}
-
-bool jar_mod_setcfg(jar_mod_context_t * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter)
-{
- if( modctx )
- {
- modctx->playrate = samplerate;
-
- if( stereo )
- modctx->stereo = 1;
- else
- modctx->stereo = 0;
-
- if(stereo_separation < 4)
- {
- modctx->stereo_separation = stereo_separation;
- }
-
- if( bits == 8 || bits == 16 )
- modctx->bits = bits;
- else
- modctx->bits = 16;
-
- if( filter )
- modctx->filter = 1;
- else
- modctx->filter = 0;
-
- return 1;
- }
-
- return 0;
-}
-
-// make certain that mod_data stays in memory while playing
-static bool jar_mod_load( jar_mod_context_t * modctx, void * mod_data, int mod_data_size )
-{
- muint i, max;
- unsigned short t;
- sample *sptr;
- unsigned char * modmemory,* endmodmemory;
-
- modmemory = (unsigned char *)mod_data;
- endmodmemory = modmemory + mod_data_size;
-
-
-
- if(modmemory)
- {
- if( modctx )
- {
- memcopy(&(modctx->song.title),modmemory,1084);
-
- i = 0;
- modctx->number_of_channels = 0;
- while(modlist[i].numberofchannels)
- {
- if(memcompare(modctx->song.signature,modlist[i].signature,4))
- {
- modctx->number_of_channels = modlist[i].numberofchannels;
- }
-
- i++;
- }
-
- if( !modctx->number_of_channels )
- {
- // 15 Samples modules support
- // Shift the whole datas to make it look likes a standard 4 channels mod.
- memcopy(&(modctx->song.signature), "M.K.", 4);
- memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130);
- memclear(&(modctx->song.samples[15]), 0, 480);
- modmemory += 600;
- modctx->number_of_channels = 4;
- }
- else
- {
- modmemory += 1084;
- }
-
- if( modmemory >= endmodmemory )
- return 0; // End passed ? - Probably a bad file !
-
- // Patterns loading
- for (i = max = 0; i < 128; i++)
- {
- while (max <= modctx->song.patterntable[i])
- {
- modctx->patterndata[max] = (note*)modmemory;
- modmemory += (256*modctx->number_of_channels);
- max++;
-
- if( modmemory >= endmodmemory )
- return 0; // End passed ? - Probably a bad file !
- }
- }
-
- for (i = 0; i < 31; i++)
- modctx->sampledata[i]=0;
-
- // Samples loading
- for (i = 0, sptr = modctx->song.samples; i <31; i++, sptr++)
- {
- t= (sptr->length &0xFF00)>>8 | (sptr->length &0xFF)<<8;
- sptr->length = t*2;
-
- t= (sptr->reppnt &0xFF00)>>8 | (sptr->reppnt &0xFF)<<8;
- sptr->reppnt = t*2;
-
- t= (sptr->replen &0xFF00)>>8 | (sptr->replen &0xFF)<<8;
- sptr->replen = t*2;
-
-
- if (sptr->length == 0) continue;
-
- modctx->sampledata[i] = (char*)modmemory;
- modmemory += sptr->length;
-
- if (sptr->replen + sptr->reppnt > sptr->length)
- sptr->replen = sptr->length - sptr->reppnt;
-
- if( modmemory > endmodmemory )
- return 0; // End passed ? - Probably a bad file !
- }
-
- // States init
-
- modctx->tablepos = 0;
- modctx->patternpos = 0;
- modctx->song.speed = 6;
- modctx->bpm = 125;
- modctx->samplenb = 0;
-
- modctx->patternticks = (((long)modctx->song.speed * modctx->playrate * 5)/ (2 * modctx->bpm)) + 1;
- modctx->patternticksaim = ((long)modctx->song.speed * modctx->playrate * 5) / (2 * modctx->bpm);
-
- modctx->sampleticksconst = 3546894UL / modctx->playrate; //8448*428/playrate;
-
- for(i=0; i < modctx->number_of_channels; i++)
- {
- modctx->channels[i].volume = 0;
- modctx->channels[i].period = 0;
- }
-
- modctx->mod_loaded = 1;
-
- return 1;
- }
- }
-
- return 0;
-}
-
-void jar_mod_fillbuffer( jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf )
-{
- unsigned long i, j;
- unsigned long k;
- unsigned char c;
- unsigned int state_remaining_steps;
- int l,r;
- int ll,lr;
- int tl,tr;
- short finalperiod;
- note *nptr;
- channel *cptr;
-
- if( modctx && outbuffer )
- {
- if(modctx->mod_loaded)
- {
- state_remaining_steps = 0;
-
- if( trkbuf )
- {
- trkbuf->cur_rd_index = 0;
-
- memcopy(trkbuf->name,modctx->song.title,sizeof(modctx->song.title));
-
- for(i=0;i<31;i++)
- {
- memcopy(trkbuf->instruments[i].name,modctx->song.samples[i].name,sizeof(trkbuf->instruments[i].name));
- }
- }
-
- ll = modctx->last_l_sample;
- lr = modctx->last_r_sample;
-
- for (i = 0; i < nbsample; i++)
- {
- //---------------------------------------
- if( modctx->patternticks++ > modctx->patternticksaim )
- {
- if( !modctx->patterndelay )
- {
- nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
- nptr = nptr + modctx->patternpos;
- cptr = modctx->channels;
-
- modctx->patternticks = 0;
- modctx->patterntickse = 0;
-
- for(c=0;c<modctx->number_of_channels;c++)
- {
- worknote((note*)(nptr+c), (channel*)(cptr+c),(char)(c+1),modctx);
- }
-
- if( !modctx->jump_loop_effect )
- modctx->patternpos += modctx->number_of_channels;
- else
- modctx->jump_loop_effect = 0;
-
- if( modctx->patternpos == 64*modctx->number_of_channels )
- {
- modctx->tablepos++;
- modctx->patternpos = 0;
- if(modctx->tablepos >= modctx->song.length)
- {
- modctx->tablepos = 0;
- modctx->loopcount++; // count next loop
- }
- }
- }
- else
- {
- modctx->patterndelay--;
- modctx->patternticks = 0;
- modctx->patterntickse = 0;
- }
-
- }
-
- if( modctx->patterntickse++ > (modctx->patternticksaim/modctx->song.speed) )
- {
- nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
- nptr = nptr + modctx->patternpos;
- cptr = modctx->channels;
-
- for(c=0;c<modctx->number_of_channels;c++)
- {
- workeffect(nptr+c, cptr+c);
- }
-
- modctx->patterntickse = 0;
- }
-
- //---------------------------------------
-
- if( trkbuf && !state_remaining_steps )
- {
- if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
- {
- memclear(&trkbuf->track_state_buf[trkbuf->nb_of_state], 0, sizeof(tracker_state));
- }
- }
-
- l=0;
- r=0;
-
- for(j =0, cptr = modctx->channels; j < modctx->number_of_channels ; j++, cptr++)
- {
- if( cptr->period != 0 )
- {
- finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod;
- if( finalperiod )
- {
- cptr->samppos += ( (modctx->sampleticksconst<<10) / finalperiod );
- }
-
- cptr->ticks++;
-
- if( cptr->replen<=2 )
- {
- if( (cptr->samppos>>10) >= (cptr->length) )
- {
- cptr->length = 0;
- cptr->reppnt = 0;
-
- if( cptr->length )
- cptr->samppos = cptr->samppos % (((unsigned long)cptr->length)<<10);
- else
- cptr->samppos = 0;
- }
- }
- else
- {
- if( (cptr->samppos>>10) >= (unsigned long)(cptr->replen+cptr->reppnt) )
- {
- cptr->samppos = ((unsigned long)(cptr->reppnt)<<10) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<10));
- }
- }
-
- k = cptr->samppos >> 10;
-
- if( cptr->sampdata!=0 && ( ((j&3)==1) || ((j&3)==2) ) )
- {
- r += ( cptr->sampdata[k] * cptr->volume );
- }
-
- if( cptr->sampdata!=0 && ( ((j&3)==0) || ((j&3)==3) ) )
- {
- l += ( cptr->sampdata[k] * cptr->volume );
- }
-
- if( trkbuf && !state_remaining_steps )
- {
- if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
- {
- trkbuf->track_state_buf[trkbuf->nb_of_state].number_of_tracks = modctx->number_of_channels;
- trkbuf->track_state_buf[trkbuf->nb_of_state].buf_index = i;
- trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern = modctx->song.patterntable[modctx->tablepos];
- trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_pos = modctx->patternpos / modctx->number_of_channels;
- trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_table_pos = modctx->tablepos;
- trkbuf->track_state_buf[trkbuf->nb_of_state].bpm = modctx->bpm;
- trkbuf->track_state_buf[trkbuf->nb_of_state].speed = modctx->song.speed;
- trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_effect = cptr->effect_code;
- trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_parameffect = cptr->parameffect;
- trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = finalperiod;
- trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_volume = cptr->volume;
- trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].instrument_number = (unsigned char)cptr->sampnum;
- }
- }
- }
- }
-
- if( trkbuf && !state_remaining_steps )
- {
- state_remaining_steps = trkbuf->sample_step;
-
- if(trkbuf->nb_of_state < trkbuf->nb_max_of_state)
- trkbuf->nb_of_state++;
- }
- else
- {
- state_remaining_steps--;
- }
-
- tl = (short)l;
- tr = (short)r;
-
- if ( modctx->filter )
- {
- // Filter
- l = (l+ll)>>1;
- r = (r+lr)>>1;
- }
-
- if ( modctx->stereo_separation == 1 )
- {
- // Left & Right Stereo panning
- l = (l+(r>>1));
- r = (r+(l>>1));
- }
-
- // Level limitation
- if( l > 32767 ) l = 32767;
- if( l < -32768 ) l = -32768;
- if( r > 32767 ) r = 32767;
- if( r < -32768 ) r = -32768;
-
- // Store the final sample.
- outbuffer[(i*2)] = l;
- outbuffer[(i*2)+1] = r;
-
- ll = tl;
- lr = tr;
-
- }
-
- modctx->last_l_sample = ll;
- modctx->last_r_sample = lr;
-
- modctx->samplenb = modctx->samplenb+nbsample;
- }
- else
- {
- for (i = 0; i < nbsample; i++)
- {
- // Mod not loaded. Return blank buffer.
- outbuffer[(i*2)] = 0;
- outbuffer[(i*2)+1] = 0;
- }
-
- if(trkbuf)
- {
- trkbuf->nb_of_state = 0;
- trkbuf->cur_rd_index = 0;
- trkbuf->name[0] = 0;
- memclear(trkbuf->track_state_buf, 0, sizeof(tracker_state) * trkbuf->nb_max_of_state);
- memclear(trkbuf->instruments, 0, sizeof(trkbuf->instruments));
- }
- }
- }
-}
-
-//resets internals for mod context
-static bool jar_mod_reset( jar_mod_context_t * modctx)
-{
- if(modctx)
- {
- memclear(&modctx->song, 0, sizeof(modctx->song));
- memclear(&modctx->sampledata, 0, sizeof(modctx->sampledata));
- memclear(&modctx->patterndata, 0, sizeof(modctx->patterndata));
- modctx->tablepos = 0;
- modctx->patternpos = 0;
- modctx->patterndelay = 0;
- modctx->jump_loop_effect = 0;
- modctx->bpm = 0;
- modctx->patternticks = 0;
- modctx->patterntickse = 0;
- modctx->patternticksaim = 0;
- modctx->sampleticksconst = 0;
- modctx->samplenb = 0;
- memclear(modctx->channels, 0, sizeof(modctx->channels));
- modctx->number_of_channels = 0;
- modctx->mod_loaded = 0;
- modctx->last_r_sample = 0;
- modctx->last_l_sample = 0;
-
- return jar_mod_init(modctx);
- }
- return 0;
-}
-
-void jar_mod_unload( jar_mod_context_t * modctx)
-{
- if(modctx)
- {
- if(modctx->modfile)
- {
- JARMOD_FREE(modctx->modfile);
- modctx->modfile = 0;
- modctx->modfilesize = 0;
- modctx->loopcount = 0;
- }
- jar_mod_reset(modctx);
- }
-}
-
-mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
-{
- mulong fsize = 0;
- if(modctx->modfile)
- {
- JARMOD_FREE(modctx->modfile);
- modctx->modfile = 0;
- }
-
- FILE *f = fopen(filename, "rb");
- if(f)
- {
- fseek(f,0,SEEK_END);
- fsize = ftell(f);
- fseek(f,0,SEEK_SET);
-
- if(fsize && fsize < 32*1024*1024)
- {
- modctx->modfile = JARMOD_MALLOC(fsize);
- modctx->modfilesize = fsize;
- memset(modctx->modfile, 0, fsize);
- fread(modctx->modfile, fsize, 1, f);
- fclose(f);
-
- if(!jar_mod_load(modctx, (void*)modctx->modfile, fsize)) fsize = 0;
- } else fsize = 0;
- }
- return fsize;
-}
-
-mulong jar_mod_current_samples(jar_mod_context_t * modctx)
-{
- if(modctx)
- return modctx->samplenb;
-
- return 0;
-}
-
-// Works, however it is very slow, this data should be cached to ensure it is run only once per file
-mulong jar_mod_max_samples(jar_mod_context_t * ctx)
-{
- mint buff[2];
- mulong len;
- mulong lastcount = ctx->loopcount;
-
- while(ctx->loopcount <= lastcount)
- jar_mod_fillbuffer(ctx, buff, 1, 0);
-
- len = ctx->samplenb;
- jar_mod_seek_start(ctx);
-
- return len;
-}
-
-// move seek_val to sample index, 0 -> jar_mod_max_samples is the range
-void jar_mod_seek_start(jar_mod_context_t * ctx)
-{
- if(ctx && ctx->modfile)
- {
- muchar* ftmp = ctx->modfile;
- mulong stmp = ctx->modfilesize;
- muint lcnt = ctx->loopcount;
-
- if(jar_mod_reset(ctx)){
- jar_mod_load(ctx, ftmp, stmp);
- ctx->modfile = ftmp;
- ctx->modfilesize = stmp;
- ctx->loopcount = lcnt;
- }
- }
-}
-
-#endif // end of JAR_MOD_IMPLEMENTATION
-//-------------------------------------------------------------------------------
-
-
-#endif //end of header file \ No newline at end of file