home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / FMODDOC.TXT < prev    next >
Text File  |  1996-01-05  |  86KB  |  2,100 lines

  1. /* (tabstops=8)
  2. ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░
  3.  
  4.  ■ MOD Player Tutorial by FireLight ■ Copyright (c) Brett Paterson 1994-95 ■
  5.                ■ Last updated 16/6/95 ■
  6.  
  7. ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░
  8.  
  9.  
  10. ┌────────────────────────────────────────────────────────────────────────────┐
  11. │                           ░▒▓ : SECTION 0: ▓▒░                             │
  12. │                           ░▒▓     Index    ▓▒░                             │
  13. └────────────────────────────────────────────────────────────────────────────┘
  14.  
  15. Section 1 : INTRODUCTION
  16.         1.1 Notes
  17.         1.2 Terminology
  18.         1.3 Contacting FireLight and feedback
  19.         1.4 Future versions
  20. Section 2 : THE LOADER
  21.         2.1 Notes
  22.         2.2 Verification
  23.         2.3 Load Module Name
  24.         2.4 Load Sample Information
  25.         2.5 Load Order Information
  26.         2.6 Load Pattern Data
  27.               2.6.1 Four bytes?
  28.         2.7 Load Sample Data
  29.         2.8 Phew :)
  30. Section 3 : PLAYING THE MOD
  31.         3.1 Ok Where Do I Start?
  32.         3.2 Setting The Timer's Speed
  33.         3.3 Player Logic
  34.               3.3.1   Orders/Patterns
  35.         3.4 Inside Update Row
  36.         3.5 Period Frequencies and Fine Tune
  37.               3.5.1   What do I do with this table?
  38.               3.5.2   Gravis UltraSound :)
  39.         3.6 Volume
  40. Section 4 : MISCELLANEOUS
  41.         4.1 Notes Without Instrument Numbers or Frequencies
  42. Section 5 : EFFECTS
  43.         5.1 Effect 0xy (Arpeggio)
  44.         5.2 Effect 1xy (Porta Up)
  45.         5.3 Effect 2xy (Porta Down)
  46.         5.4 Effect 3xy (Porta To Note)
  47.         5.5 Effect 4xy (Vibrato)
  48.         5.6 Effect 5xy (Porta + Vol Slide)
  49.         5.7 Effect 6xy (Vibrato + Vol Slide)
  50.         5.8 Effect 7xy (Tremolo)
  51.         5.9 Effect 8xy (Pan)
  52.         5.10 Effect 9xy (Sample Offset)
  53.         5.11 Effect Axy (Volume Slide)
  54.         5.12 Effect Bxy (Jump To Pattern)
  55.         5.13 Effect Cxy (Set Volume)
  56.         5.14 Effect Dxy (Pattern Break)
  57.         5.15 Effect Fxy (Set Speed)
  58.         5.16 Effect E0x (Set Filter)
  59.         5.17 Effect E1x (Fine Porta Up)
  60.         5.18 Effect E2x (Fine Porta Down)
  61.         5.19 Effect E3x (Glissando Control)
  62.         5.20 Effect E4x (Set Vibrato Waveform)
  63.         5.21 Effect E5x (Set Finetune)
  64.         5.22 Effect E6x (Pattern Loop)
  65.         5.23 Effect E7x (Set Tremolo WaveForm)
  66.         5.24 Effect E8x (Unused)
  67.         5.25 Effect E9x (Retrig Note)
  68.         5.26 Effect EAx (Fine Volume Slide Up)
  69.         5.27 Effect EBx (Fine Volume Slide Down)
  70.         5.28 Effect ECx (Cut Note)
  71.         5.29 Effect EDx (Delay Note)
  72.         5.30 Effect EEx (Pattern Delay)
  73.         5.31 Effect EFx (Invert Loop)
  74.  
  75. Section 6 : APPENDIX - MOD FORMAT DOCUMENT
  76.  
  77. ┌────────────────────────────────────────────────────────────────────────────┐
  78. │                           ░▒▓ : SECTION 1: ▓▒░                             │
  79. │                           ░▒▓ Introduction ▓▒░                             │
  80. └────────────────────────────────────────────────────────────────────────────┘
  81.  
  82. ┌───────────────────┐
  83. │ ░▒▓ 1.1 Notes ▓▒░ │
  84. └───────────────────┘
  85.  
  86. New in this version: 
  87. - Loader mistake fixed in section 2.6 ->
  88.       - store SAMPLE_NUMBER as    (byte1 AND 0F0h) + (byte2 SHR 4)
  89.       should have been                 ^
  90.       - store SAMPLE_NUMBER as    (byte0 AND 0F0h) + (byte2 SHR 4)
  91.                        ^
  92. - Section 3.4, Inside Update row rewritten, the old one was weird and crap
  93. - Pattern break and pattern jump more accurately described
  94. - New section 2.6.1 - Four bytes?
  95. - Section 3.5.1 rewritten.
  96.  
  97. Preamble:
  98. =========
  99. I am covering the .MOD format here basically because it's not a very good
  100. idea to try and leap into a harder format like xm or s3m without prior
  101. knowledge.  MOD still *IS* the most widely spread format so there's nothing
  102. wrong with coding a player for it.  S3M is the next step up because it is
  103. basically just a wider .MOD with more octaves and a volume byte.  (blah yeah
  104. I know there are 99 samples and more effects, that's just cosmetic though.)
  105. (ie s3m still use the same crap amiga frequencies as mod - for a PC format!).
  106.  
  107. Assumptions:
  108. ============
  109. Throughout the document, exaggerated length variable names are used, I don't
  110. actually use these sort of variable names but they help to make things 
  111. clearer. eg "NUMBER_OF_PATTERNS".  Variable names will be all stated in 
  112. capitals.
  113.  
  114. It is assumed you will have some sort of knowledge about
  115.     - Sound Cards (and programming of sound cards, though I do include
  116.             gus code in fmoda.asm)
  117.     - Interrupt Handlers (I will cover this a bit though)
  118.  
  119. Most of the time I present a type of pseudocode to try not to seem to biased
  120. towards a language, but some examples I have used straight C code only to
  121. demonstrate how I did it.  C should be fairly intuitive to read so most
  122. people wont have that hard a time figuring it out.
  123.  
  124. ┌─────────────────────────┐
  125. │ ░▒▓ 1.2 Terminology ▓▒░ │
  126. └─────────────────────────┘
  127.      
  128.      TYPE    LENGTH  Bits    RANGE                   BORLAND/TURBO C
  129.      ────────────────────────────────────────────────────────────────────
  130.      byte    1       8       0-255                   unsigned char
  131.      word    2       16      0-65,535                unsigned int
  132.      dword   4       32      0-4,294,967,295         unsigned long
  133.      ────────────────────────────────────────────────────────────────────
  134. Throughout this text I use the terms BYTE,WORD, and DWORD, to make the
  135. document more general to all languages.  In C you can use typedefs to achieve
  136. the use of byte,word,dword terminology, and in pascal and asm the syntax is
  137. already suited to this anyway.
  138.  
  139. ORDERS   - orders are how the mod plays from 0 to length of song.
  140. PATTERNS - patterns are played in any ORDER, and are the physical information.
  141.  
  142. TICK - I refer to a clock tick for the interrupt handler as a tick, some
  143. others use the term FRAME.  I will be using the term tick throughout the whole
  144. document.
  145.  
  146. ┌───────────────────────────────────────────────┐
  147. │ ░▒▓ 1.3 Contacting FireLight and feedback ▓▒░ │
  148. └───────────────────────────────────────────────┘
  149.  
  150. Contact is encouraged because I think I have left out some things and 
  151. probably made some mistakes (not that I can see), and would like you to
  152. tell me about them.
  153.  
  154. email : firelght@yoyo.cc.monash.edu.au 
  155.  post : Brett Paterson,                
  156.     48/a Parr st,
  157.     Leongatha, 3953,
  158.     Victoria, Australia.
  159. phone : AU (056) 623795                
  160.   IRC : FireLight on #coders, #trax or #aussies
  161.  
  162. ┌─────────────────────────────┐
  163. │ ░▒▓ 1.4 Future versions ▓▒░ │
  164. └─────────────────────────────┘
  165. Im really starting to get into this stuff, so here is what will appear in
  166. future versions of this document.
  167.  
  168. o Mixing techniques - This is a very important section and I really want this
  169.             to be included in here but need an experienced SB mod
  170.             coder to write this section for me (anyone out there!!!)
  171. o How to handle multiple formats - talking about your internal format for
  172.             handling multiple formats.  I am currently updating fmod
  173.             to support s3m and mtm and so info on these formats will
  174.             be included.
  175.  
  176. ┌────────────────────────────────────────────────────────────────────────────┐
  177. │                           ░▒▓ : SECTION 2 : ▓▒░                            │
  178. │                           ░▒▓  The Loader   ▓▒░                            │
  179. └────────────────────────────────────────────────────────────────────────────┘
  180.  
  181. ┌───────────────────┐
  182. │ ░▒▓ 2.1 Notes ▓▒░ │
  183. └───────────────────┘
  184. Well first we've got to load the module in right?  Following is a step by
  185. step way to code your loader, and storage issues will be discussed to help
  186. you along.  I really don't feel like just writing another MOD format
  187. description, so you will find one in the appendix of section 6 written by
  188. lars hamre(?), the author of protracker.
  189.  
  190. You WILL need to refer to the format document and this document side by side.
  191. The loader section of this document doesnt actually give a map of mod format
  192. and could be confusing, though it does go through it byte by byte.
  193.  
  194. The following section has their subsections which are in boxes, and in each
  195. of these sections are 3 important subsections
  196.  
  197. - EXPLANATION   (describes what the section is on about, for understanding)
  198. - PSEUDOCODE    (actually shows HOW to load the information)
  199. - STORAGE ISSUE (helps on how to store the information loaded)
  200. - SUGGESTION    (a helpfull hint or suggestion to do after this step)
  201.  
  202. I placed the pseudocode section before storage issues because I know you are
  203. probably going to be eager and want to jump into some code straight away.
  204. Storage issue follows just to be a guiding hand; not a 'must'.
  205. each pseudocode section follows on from the last.
  206.  
  207. ┌──────────────────────────┐
  208. │ ░▒▓ 2.2 Verification ▓▒░ │
  209. └──────────────────────────┘
  210.  
  211. Explanation:
  212. ============
  213. Before we attempt to load a mod, we should check that it is in fact a mod.
  214. Every mod has a unique signature, and in case of the .MOD format, this is 
  215. in the form of a 4 letter string containing the letters "M.K.", or "8CHN" or
  216. a variety of other signatures for their mutated formats :)
  217.   These describe the type of mod, and the identifier signature is stored at
  218. offset 1080 (438h) in the file, so should be checked first.
  219.  
  220.  
  221. PseudoCode:
  222. ===========
  223. - Seek to offset 1080 (438h) in the file
  224. - read in 4 bytes
  225. -           compare them to "M.K."  - if true we have a 4 channel mod
  226. - otherwise compare them to "6CHN"  - if true we have a 6 channel mod
  227. - otherwise compare them to "8CHN"  - if true we have an 8 channel mod
  228. - otherwise exit and display error message.
  229.  
  230. There are also rare tunes that use **CH where ** = 10-32 channels
  231.  
  232. Suggestion:
  233. ===========
  234. Use this point to store the number of channels in a variable of your choice
  235. (I just use a global variable called CHANNELS)
  236.  
  237.  
  238. ┌──────────────────────────────┐
  239. │ ░▒▓ 2.3 Load Module Name ▓▒░ │
  240. └──────────────────────────────┘
  241.  
  242. Explanation:
  243. ============
  244. This is a trivial part of the loader and just holds the Title or name of the
  245. mod.  It is the very first 20 bytes of the MOD.
  246.  
  247. PsuedoCode:
  248. ===========
  249. - Seek back to position 0, the start of the file
  250. - read in 20 bytes, store as MODULE_NAME.
  251.  
  252. Storage Issue:
  253. ==============
  254. The name of the module is a 20 byte string, padded by 0's.
  255. Here you can either store your module name as a global variable, in a
  256. character string, or do what I do and store all the general information about
  257. the mod in a structure like this
  258.  
  259. struct MODHEADER {
  260.     char NAME[20]
  261.     ...
  262.     other information (will get to this later)
  263.     ...
  264. } MODHEAD
  265.  
  266. OR just
  267.  
  268. char NAME[20]
  269.  
  270. It's a good idea to set up a structure like this for future use, there is a
  271. lot more infomration we will need to throw in here later, but of course you
  272. don't need a structure, you can keep it as a heap of loose variables :)
  273. And of course if you are not interested in displaying the name of the module
  274. you could just discard it.
  275.  
  276. Suggestion:
  277. ===========
  278. Code a 1 line program to print out the name of your module to see if it's
  279. working properly. (exciting huh :)
  280.  
  281. NOTE: The Module name is supposed to be padded by 0's, and terminated with a
  282.       0, but sometimes this is not the case.  Sometimes a tracker will allow
  283.       all 20 bytes to store characters, which means no NULL termintor byte.
  284.     This causes functions like printf to give unpredictable output as it 
  285.       cannot find the NULL terminator.  The way to fix this is just to use a 
  286.       loop and print out each character one at a time, or overwrite the 20th
  287.       byte with a 0.
  288.  
  289. ┌─────────────────────────────────────┐
  290. │ ░▒▓ 2.4 Load Sample Information ▓▒░ │
  291. └─────────────────────────────────────┘
  292.  
  293. Explanation:
  294. ============
  295. Sample information is stored at the start of a MOD file, and contains all the
  296. relevant information for each of the 31 samples.  This includes its name,
  297. length, loop points, finetune etc..
  298. So from here we loop 31 times and read in a block of information about the 
  299. sample according to the loop counter.
  300.  
  301. PseudoCode:
  302. ===========
  303. - from this point, loop 31 times
  304.     - for the sample # <loopcounter>....
  305.     - read in 22 bytes,       store as SAMPLE_NAME
  306.     - read in 2 bytes (word), store as SAMPLE_LENGTH  *   \
  307.     - read in 1 byte,         store as FINE_TUNE      @   /\ IMPORTANT:
  308.     - read in 1 byte,         store as VOLUME               } see key
  309.     - read in 2 bytes (word), store as LOOP_START     *   \/   below
  310.     - read in 2 bytes (word), store as LOOP_LENGTH    *   /
  311. - end of loop
  312.  
  313. KEY:
  314. * to get the real value in bytes, calculate it with (byte1*100h + byte2) * 2
  315. @ for FINE_TUNE, if the value is > 7, subtract 16 from it to get the signed
  316.    value (ie. 0-7 = 0-7, and 8-15 = -8 to -1)
  317.  
  318. Storage Issue:
  319. ==============
  320. I think the best way to store information on the 31 instruments, is to store
  321. its information in a structure, then have an array of 31 of these intstrument
  322. structures. Like this :
  323.  
  324. struct SAMPLE {
  325.     char SAMPLE_NAME[22]
  326.     word SAMPLE_LENGTH
  327.     byte FINE_TUNE
  328.     byte VOLUME
  329.     word LOOP_START
  330.     word LOOP_LENGTH
  331.  
  332.     (also some physical position information - see sample loading section.
  333.      some possibilities are under GUS...
  334.  
  335.     dword GUS_OFFSET
  336.  
  337.     OR using main memory with sb say..
  338.     
  339.     char *SAMP_BUFF (pointer to the actual physical data in memory)
  340. }
  341.  
  342. now declare an array of 31 SAMPLEs.  I do this in the general mod header 
  343. structure which is explained fully in the next section.
  344. The other way which can be used is just to keep a heap of global arrays like
  345. this;
  346.  
  347. char SAMPLE_NAME[31][22]
  348. word SAMPLE_LENGTH[31]
  349. byte FINE_TUNE[31]
  350. byte VOLUME[31]
  351. word LOOP_START[31]
  352. word LOOP_LENGTH[31]
  353.  
  354. Suggestion:
  355. ===========
  356. Now code a little viewer once you have done this to make sure everything is
  357. stored properly.  This is VERY a important step.  Compare your output to
  358. the tracker it came from or a player that shows all sample information.
  359.  
  360.  
  361. ┌────────────────────────────────────┐
  362. │ ░▒▓ 2.5 Load Order Information ▓▒░ │
  363. └────────────────────────────────────┘
  364.  
  365. Explanation:
  366. ============
  367. Ok now sample information is loaded, the next section of the module contains
  368. order information.  Order information in a mod defines in what order patterns
  369. are going to be played.  This means the composer could set orders 0 and 1 
  370. to pattern 0, for example, and the intent would be for pattern 0 to play 
  371. twice.  Its entry in the order table would look like this.
  372.  
  373. ORDER  : 0 1 2 3 4 5 6 7 8 9
  374. PATTERN: 0 0 
  375.  
  376. Note orders have to be from 0 to length of song, but patterns can be chopped
  377. and changed around in any order.
  378. The first byte from here will tell us the length of the song in -orders-,
  379. even though they are stored in 128 bytes of information.
  380.  
  381. PsuedoCode:
  382. ===========
  383. - read a byte, store as SONG_LENGTH (this is the number of orders in a song)
  384. - read a byte, discard it (this is the UNUSED byte - used to be used in PT as
  385.    the restart position, but not now since jump to pattern was introduced)
  386.  
  387. Now we are at the orders table, this is 128 bytes long and contains the order
  388. of patterns that are to be played in the song.  here we have to find out how
  389. many physical patterns there are in the module.  How do we do this? Simple
  390. just check every order byte and the highest value found is stored as the
  391. number of patterns in the song.
  392.  
  393. - set NUMBER_OF_PATTERNS to equal 0
  394. - from this point, loop 128 times
  395.      - read 1 byte, store it as ORDER <loopcounter>
  396.      - if this value was bigger than NUMBER_OF_PATTERNS then set it to that
  397.        value.
  398. - end of loop
  399. - read 4 bytes, discard them (we are at position 1080 again, this is M.K. etc!)
  400.  
  401. Storage Issue:
  402. ==============
  403. One way is to go back to the other original MODhead structure, which contained
  404. general infomation about the mod. here is the entire structure.
  405.  
  406. struct MODHEADER {
  407.     char NAME[20]              ; song name
  408.     SAMPLE INST[31]            ; instrument headers
  409.     byte SONG_LENGTH           ; song length
  410.     byte NUMBER_OF_PATTERNS    ; number of physical patterns
  411.     byte ORDER[128]            ; pattern playing orders
  412. } MODHEAD;
  413.  
  414. or the second way would just to be store them all as global variables
  415.  
  416. char NAME[20]                      ; song name
  417. byte SONG_LENGTH                   ; song length
  418. byte NUMBER_OF_PATTERNS            ; number of physical patterns
  419. byte ORDER[128]                    ; pattern playing orders
  420.  
  421. no array of samples here because if you saw the sample header loading section
  422. we just stored them all as their own arrays.
  423.  
  424. Suggestion:
  425. ===========
  426. As always print out the 128 orders, and see if the pattern numbers displayed
  427. are correct.  Now you should have a viewer that can just about display every
  428. bit of information about the module!  OK that stuff was easy.  Now it's time
  429. for something tougher.. the pattern data!
  430.  
  431. ┌───────────────────────────────┐
  432. │ ░▒▓ 2.6 Load Pattern Data ▓▒░ │
  433. └───────────────────────────────┘
  434.  
  435. Explanation:
  436. ============
  437.  
  438. This is about the hardest part to code of the loader, and storage issues here 
  439. are VERY important, so it will be discussed first.  Im going to try and be as 
  440. general as I can as I don't want to appear to be trying to steer you in any 
  441. direction, but I will be specific enough to guide you.
  442.  
  443. Storage Issues:
  444. ===============
  445. There are only a few ways to store pattern data, Ive spent some time pondering
  446. this issue.  I found the only viable methods of storing pattern data are -
  447.  
  448. 1- Linked List, using channels as nodes (dynamic but slow, well not THAT slow)
  449. 2- Fixed arrays (terribly memory wasting and messy)
  450. 3- Create and allocate a buffer the size we need to store all the patterns, 
  451.     and then use a roving pointer to access patterns later  (sounds ok to me)
  452.  
  453. Patterns really need to be stored DYNAMICALLY, or in other words only use as
  454. much memory as you need.
  455. Method 1   Was the method I used to begin with, for the sole reason that it is
  456.        nicely dynamic and easy.  It was quite ok to start on and was good
  457.        enough for me (with GUS), but I scrapped that idea and went for
  458.        the final method.  Method 3 is much more general to all languages
  459.        too.
  460. Method 2   Is out for this reason, it just isnt memory efficient enough.
  461.        And also you cant subscript arrays in a normal high level language
  462.        with indexes larger than 65536.  (method 3 is an extension of this)
  463. Method 3.  This method is quite easy and efficent to use and very dynamic,
  464.        once you have worked out how to allocate and access huge pointers
  465.        which can be up to 640kb big :)  Players that seem to use this 
  466.        method are GUSPlay by Cascada, and ProTracker by Lars Hamre.
  467.        FireMod 1.02 and higher, by myself uses this method.
  468.  
  469. It works this way:
  470.  
  471. - declare a pointer and allocate it the amount of memory calculated below;
  472.  
  473.       CHANNELS * 4 * 64 * (NUMBER_OF_PATTERNS+1)
  474.              │   │
  475.              │   └─── (rows per channel)
  476.              └─────── (bytes per note)
  477.  
  478. Why add 1 to NUMBER_OF_PATTERNS? well because patterns start at 0, and finish
  479. at NUMBER_OF_PATTERNS, hence the aditional 1.  If you didnt add 1 and there
  480. was only 1 pattern you would end up allocating 0 bytes for the pattern data :)
  481.  
  482. This value is normally going to be a very big number, so a dword will be
  483. needed to store it.  I initially had problems with data wrapping around at
  484. 64kb with my buffer using char far *, (say if it was 500kb large), but this
  485. was fixed by delcaring it with the huge keyword (look up online help to find
  486. out more) - eg : char huge *patbuff.
  487.  
  488. So to find the physical pattern in your pattern buffer, calculate the offset
  489. with the formula (channels * 4 * 64) * pattno.
  490. Say we want to point to the start of pattern 4 in an 8CHN mod.
  491.   (8 * 4 * 64) * 4
  492.   = 8192.
  493. So as you travel through this pattern just increment your pointer by 4 bytes
  494. at a time.
  495.  
  496. A note is stored in the actuall file as 4 bytes, it is done in this fashion.  
  497. The pseudocode below shows how to unravel this amigafied mess :)
  498.  
  499. ┌─────────────────────────────────────┐
  500. │ Byte 0    Byte 1   Byte 2   Byte 3  │
  501. │─────────────────────────────────────│
  502. │aaaaBBBB CCCCCCCCC DDDDeeee FFFFFFFFF│
  503. └─────────────────────────────────────┘
  504. aaaaDDDD     = sample number
  505. BBBBCCCCCCCC = sample period value
  506. eeee         = effect number
  507. FFFFFFFF     = effect parameters
  508.  
  509. PseudoCode:
  510. ===========
  511. - calculate amount of memory needed for NUMBER_OF_PATTERNS patterns like so:
  512.     CHANNELS * 4 * 64 * (NUMBER_OF_PATTERNS+1)
  513. - create a base pointer and allocate the memory needed
  514. - From this point, loop for as many times as NUMBER_OF_PATTERNS
  515.      - From this point, loop 64 * CHANNELS times (this equals 1 pattern)
  516.       - read 4 bytes
  517.       - store SAMPLE_NUMBER as    (byte0 AND 0F0h) + (byte2 SHR 4)
  518.       - store PERIOD_FREQUENCY as ((byte0 AND 0Fh) SHL 8) + byte1;
  519.       - store EFFECT_NUMBER as    byte2 AND 0Fh
  520.       - store EFFECT_PARAMETER as byte 3
  521.       - increment pattern pointer by 4 bytes
  522.      - end loop
  523. - end loop
  524.  
  525. OK:
  526. ===
  527. Alright so lets look at this again in simpler terms:
  528.  - We have a big buffer that is meant to store all the pattern data
  529.  - Then we start loading in the notes *4* bytes at a time, and unravel them
  530.      into something meaningful as shown above.
  531.  - store the new note variables one after the other, and it should fill the
  532.      buffer to the exact size as was allocated in the beginning.
  533.  
  534. Suggestion:
  535. ===========
  536. With EFFECT_PARAMTER, you might be tempted to store the 2 values stored in
  537. here as 2 seperate variables, eg. EFFECT_PARAMETER_X, and EFFECT_PARAMETER_Y.
  538. I used to store them this way but I assure you when you get into coding your
  539. effects this this method is quite inefficient, I saved memory and increased
  540. speed (but not noticably :) just by storing them in the 1 byte, and splitting
  541. them only in the few times that you do need it. (i.e, printing them out
  542. separately, or vibrato, or for finding out which E (extra) effect to use etc.)
  543.  
  544. ┌───────────────────────────┐
  545. │ ░▒▓ 2.6.1 Four bytes? ▓▒░ │ *IMPORTANT*
  546. └───────────────────────────┘
  547.  
  548. At this stage you're probably thinking.. how do I fit all this into only 4
  549. bytes?
  550. For a start, DONT store the amiga periods as your note value.  Convert each
  551. period to a note number.  **See section 3.5.1** for more discussion on notes
  552. and frequencies.  In summary you just scan through the amiga table until it
  553. matches the value you loaded in.
  554.  
  555. Anyway even if you did store the amiga period value as your note (which you
  556. wont), then you can still fit it all into 4 bytes.  The file did it so why
  557. cant you.
  558. I use bit allocation.  This means I only use the bits I need in a byte, and
  559. not a whole byte.
  560.  
  561. An example of this is the note volume is only capable of getting up to 64, so
  562. we only need 6 bits.  The sample number goes up to 31.  This only needs 5
  563. bits.  Follow here and see how things are allocated.  This is similar to the
  564. way I do it in my player.  In C you can allocate a variable and tell how many
  565. bits you want to use.  In asm i'd say you would have to use a 4 bytes, and do 
  566. the bit calculations yourself before you access them, which shouldnt be too 
  567. hard.
  568.  
  569. int note:11;    // 0-??  = 11 bits = 0-2048 should be plenty for your needs.
  570. byte number:5;  // 0-31  = 5 bits
  571. byte effect;    // 0-15  = 4 bits, but use 8 to keep things even
  572. byte eparm;     // 0-255 = 8 bits
  573.  
  574. I actually use 3 bytes for my new player.  I first convert finetunes to a
  575. middle C value in hz like s3m (see st3's tech.doc how this works), therefore 
  576. I only need the amiga table for the actual notes and not the finetunes 
  577. between.
  578. So I get something like note=7bits, number=5bits, effect=4bits, eparm=8bits,
  579. = 7+5+4+8 = 24 = 3bytes!
  580.  
  581. ┌──────────────────────────────┐
  582. │ ░▒▓ 2.7 Load Sample Data ▓▒░ │
  583. └──────────────────────────────┘
  584.  
  585. PsuedoCode:
  586. ===========
  587. - From this point, loop 31 times
  588.      - get the length of the sample # <loopcounter> (stored in your variable)
  589.  
  590. At this point I use only GUS, and dump the sample to the GUS dram, but I
  591. could imagine if you were using Sound Blaster etc, you would just declare 31
  592. pointers in memory and allocate them a SAMPLE_LENGTH sized buffer, then load
  593. the information into those buffers.  When you need to play them you would mix
  594. the channels into a small buffer then DMA that buffer out to the sound card.
  595.  
  596.      - [SOUNDBLASTER] allocate a SAMPLE_LENGTH sized pointer to buffer in 
  597.        memory and load the sample into it
  598.      - [DRAM-BASED-CARD (GUS)] poke/DMA bytes into DRAM, increment dword
  599.        offset value GUS_OFFSET, and store that value next to the sample's
  600.        information (along side length, volume, finetune, loop start etc)
  601.      - check that your samples fit into (D)RAM, and exit with an error if
  602.        they don't.
  603. - end loop
  604.  
  605. ┌─────────────────────┐
  606. │ ░▒▓ 2.8 Phew :) ▓▒░ │
  607. └─────────────────────┘
  608. Wasn't that bad was it? Now you have the FULL mod file stored away at your
  609. disposal, with samples ready to blast.
  610.  
  611. Suggestions:
  612. ============
  613. Now is a GOOD time to do some thorough testing.  Do these things
  614.  
  615. - Make sure your sample headers and information are stored correctly
  616. - Make sure your pattern data is stored perfectly.. it's quite important you
  617.   know :)
  618. - Make sure your samples are stable in memory, and try to play them through
  619.   your sound card.. you can have a few problems with misloaded samples I have
  620.   found :)  Also make sure the loop points are played correctly!
  621. - Make sure you deallocate your memory before quitting the program!!
  622.  
  623.  
  624.  
  625.  
  626. ┌────────────────────────────────────────────────────────────────────────────┐
  627. │                           ░▒▓  : SECTION 3 :  ▓▒░                          │
  628. │                           ░▒▓ Playing the MOD ▓▒░                          │
  629. └────────────────────────────────────────────────────────────────────────────┘
  630.  
  631. ┌─────────────────────────────────┐
  632. │ ░▒▓ 3.1 OK where do I start ▓▒░ │
  633. └─────────────────────────────────┘
  634.  
  635. I think the main thing you need to do now once you are satisfied your MOD is
  636. loaded properly, is to set up an interrupt function, and understand a bit
  637. about the way a MOD is played.
  638.  
  639. Im going to use the system timer to hook onto here as an example, and if you
  640. want to use other interrupt servicers you can do that if you know how..
  641. (ie GUS IRQ).
  642. You should know how to set up an interrupt handler yourself, but ill describe
  643. how to do it here with a bit of code to demonstrate. 
  644.  
  645. The system timer lies on INT 8
  646. - Get the old handlers vector for int 8h, and store it away for later
  647. - Set your new handler function to the vector for int 8h
  648.  
  649.  ┌─────────────────────────────────────────────────────────────────────────┐
  650.  │ REMEMBER TO REHOOK YOUR OLD TIMER TO ITS ORIGNAL PLACE WHEN THE SONG IS │
  651.  │                               FINISHED!                                 │
  652.  └─────────────────────────────────────────────────────────────────────────┘
  653.  
  654. In C you would do that like this:
  655.     oldhandler = _dos_getvect(8);
  656.     setvect(8, handler);
  657.  
  658.  - where oldhandler has to have the prototype globally declared as 
  659.    void interrupt ( *oldhandler)(...);
  660.  - for dummies the actuall handler function looks like this
  661.    
  662.    void interrupt modhandler(...) { // yes put 3 dots in here
  663.     ...                         // do main loop here
  664.     oldmodhandler();            // this is here to return int8 to what it
  665.                     // normally did.  I'll crash without it.
  666.    }
  667.  
  668. In PASCAL it would look something like this
  669.     GetIntVec($8, Addr(OldTimer));
  670.     SetIntVec($8, Addr(ModInterrupt));
  671.  
  672.   - with the function looking something like (I have no idea if this is right
  673.                           as I don't do pascal)
  674.    { $ F+,S-,W-}
  675.    Procedure modhandler; Interrupt;
  676.    Begin
  677.    ...
  678.    OldTimer;
  679.    End;
  680.    { $ F-,S+}
  681.  
  682. If you're still not sure in C or pascal, check out the online manual on 
  683. getvect/setvect etc..
  684.  
  685. ┌───────────────────────────────────────┐
  686. │ ░▒▓ 3.2 Setting the timer's speed ▓▒░ │
  687. └───────────────────────────────────────┘
  688. Ok now your interrupt handler is already firing :) so one thing you must
  689. do is set it to the right speed, we don't want mods that play way to fast or
  690. slow, we want it at 125 BPM right now (or 50hz, or 50 ticks a second).
  691.  
  692. How do you set the system timer's speed? if we want 50hz, we have to use
  693. a divisor to calculate the right rate like so.
  694.  
  695. Speed = 1193180/50        <- 50 hz here, 1193180 is the divisor.
  696.  
  697.     mov dx, 0x43
  698.     mov al, 0x36
  699.     out dx, al
  700.     mov dx, 0x40
  701.     mov ax, Speed     <- here's the speed variable 
  702.     out dx, al
  703.     shr ax, 8
  704.     out dx, al
  705.  
  706. Now the interrupt function should be ticking away at 50 times a second.
  707. For other BPM's, which will be used because of the change tempo effect Fxy
  708. with values of 20h and up.  If it is below 20h, then you change the SPEED and
  709. not the BPM.  This is looked at later on.
  710.  
  711. To convert BPM to HZ, you use :   
  712.      HZ = 2 * BPM / 5           (i.e 125bpm = 50hz)
  713. then SPEED = 1193180 / HZ  for the set timer routine.
  714.  
  715. Simple huh.  You'll need this for effect Fxy, but don't worry about this until 
  716. later.
  717.  
  718. ┌──────────────────────────┐
  719. │ ░▒▓ 3.3 Player Logic ▓▒░ │
  720. └──────────────────────────┘
  721.  
  722. Now lets take a look at the interrupt function, this is where the playing
  723. is done.
  724.  
  725. The SPEED of a song is the base on how your mod is played.  Each row of a
  726. pattern is updated every SPEED number of clock ticks, so if a speed is 6,
  727. then you only update each row every 6 clock ticks.  So on a speed like 3,
  728. the row is going to be updated every 3 ticks and will play twice as fast as
  729. speed 6.
  730.   Inbetween you update certain tick sensitive effects, like portamentos, 
  731. volume slides and vibrato. 
  732.   Diagramatically the playing of a mod looks like this.
  733.  
  734. SPEED IS 6
  735.  
  736. tick#
  737. ┌─┘
  738. 0: UPDATE ROW #0    <- update the 4,6 or 8 notes here in a mod's row.
  739. 1: ---  \
  740. 2: ---   \
  741. 3: ---    >- certain effects are updated here
  742. 4: ---   /
  743. 5: ---  /
  744. 0: UPDATE ROW #1
  745. 1: ---
  746. 2: ---
  747. 3: ---
  748. 4: ---
  749. 5: ---
  750. 0: UPDATE ROW #2
  751. etc..
  752.  
  753. Logically a very basic representation of playing a mod looks like this:
  754. ┌─────────────────────┐
  755. │ STATIC TICK = SPEED │  - declaration, start it off at SPEED, not 0, as we
  756. │                     │    want straight into the 'if tick >= speed condition'
  757. │ TICK = TICK + 1     │  - now increment the tick counter
  758. │ if TICK >= SPEED    │  - if the tick # is bigger or equal than SPEED then
  759. │       update_row    │  - update the CHANNEL number of notes for the new row
  760. │       tick =0       │  - reset tick to 0
  761. │       ROW = ROW + 1 │  - incrememnt our row
  762. │ else update_effect  │  - else we update the tick based effects.
  763. └─────────────────────┘
  764. But you will have to take into account there are only 64 rows in a pattern,
  765. and if you hit 64 then jump to the next pattern and start at row 0 again.
  766. I say 64 because row 63's effects have to be played out before you jump to
  767. the next pattern.
  768.  
  769. don't bother with update_effect for some time until you have got update_row
  770. going ok.
  771.  
  772. ┌────────────────────────────────┐
  773. │ ░▒▓ 3.3.1  Orders/Patterns ▓▒░ │
  774. └────────────────────────────────┘
  775. Just a short note on this.
  776. When you reach the end of the pattern or whatever, you need to go to the next
  777. order.  Now say you had your order pattern numbers stored in an array as they
  778. should be, then it is simply a task of referencing that pattern number
  779. according to the index ORDER, and then repositioning your pattern pointer
  780. accordingly.
  781.  
  782. ie. If your order list is something like this.
  783.     ┌──────────────────────────┐
  784.   Order │ 0 1 2 3 4 5 6 7 8 9 .... │
  785.     │──────────────────────────│
  786. Pattern │ 0 0 1 4 5 2 3 4 4 6 .... │
  787.     └──────────────────────────┘
  788. and you have an array of patterns set up as ORDER_TABLE[128].
  789. Selecting the appropriate pattern is as simple as finding ORDER_TABLE[ORDER].
  790. To find the offset in your buffer you should know how to do by now by using
  791. some sort of formula like: 
  792.   
  793.   offset = (CHANNELS * 4 * 64 * ORDER_TABLE[ORDER])
  794.             bytes, rows
  795.  
  796. and to find the current row just add (CHANNELS * 4 * row).
  797.  
  798. so the pattern+row formula ends up as :
  799.   offset = (CHANNELS * 4 * 64 * ORDER_TABLE[ORDER]) + (CHANNELS * 4 * row).
  800.  
  801. I calculate this figure before processing every row and set the pattern
  802. pointer, so that all I have to do is increment the row number or the order
  803. number and this formula will pick it up for me and set the pointer
  804. accordingly.
  805.  
  806. ┌───────────────────────────────┐
  807. │ ░▒▓ 3.4 Inside update row ▓▒░ │
  808. └───────────────────────────────┘
  809.  
  810. Ok on every tick 0, we want to update CHANNELS number of channels
  811.  
  812. PSEUDOCODE:
  813. -----------
  814.  
  815. - Point your note pointer to the correct offset in the pattern buffer, 
  816.   according to order and row
  817.  
  818. Loop CHANNEL number of times {
  819.      get NOTE from buffer
  820.      get SAMPLE from buffer
  821.      get EFFECT from buffer
  822.      get EFFECT_PARAMETER from buffer
  823.  
  824.      if (SAMPLE > 0) then {
  825.       LAST_INSTRUMENT[CHANNEL] = SAMPLE (we store this for later)
  826.       volume[CHANNEL] = default volume of sample#
  827.       SetVolume(volume[CHANNEL])      (actually do the hardware set here)
  828.      }
  829.      if (period >= 0) then {
  830.       if (EFFECT does not = 3 and EFFECT does not = 5) then
  831.           frequency[CHANNEL] = 
  832.             FREQ_TAB[NOTE + LAST_INSTRUMENT[CHANNEL]'s finetune]
  833.      }
  834.  
  835. (freq_tab[] should be your amiga frequency lookup table - see sec 3.5)
  836.      
  837.  
  838.      (this line here is a bit of optimization for your player)
  839.      if (effect# = 0 and parameter# = 0) then jump to SKIP_EFFECTS label
  840.  
  841.      -----
  842.      -----
  843.      PROCESS THE NON TICK BASED EFFECTS (see section 5 how to do this)
  844.      ALSO GRAB PARAMETERS FOR TICK BASED EFFECTS (like porta, vibrato etc)
  845.      -----
  846.      -----
  847.  
  848. label SKIP_EFFECTS:
  849.  
  850.      if (freqency[CHANNEL] > 0) then SetFrequency(frequency[CHANNEL])
  851.      if (period > 0 OR sample_offset > 00FFh) then {
  852.              (Why 00FFh? because with sample offset anything below 
  853.               1 * 100h is considered 0.  See section 5.10 about this)
  854.       if (vibratowavecontrol = retrig waveform) then {
  855.         vibrato_position[CHANNEL] = 0 (see section 5.5 about this)
  856.         vibrato_negative[CHANNEL] = 0 (see section 5.5 about this)
  857.       }
  858.       if (tremolowavecontrol = retrig waveform) then {
  859.         tremolo_position[CHANNEL] = 0 (see section 5.8 about this)
  860.         tremolo_negative[CHANNEL] = 0 (see section 5.8 about this)
  861.       }
  862.       PLAYVOICE
  863.       * (here is gus biased, I guess for SB mixing you would mix in a 
  864.          section of the sample into a small buffer and dma it out here.  
  865.          You also have to take note if the sample is looping or not.. GUS
  866.          does this for you of course ;) )
  867.       * (also remember to add the sample_offset value to the start of the
  868.          sample begin address.  If there was no sample offset then this
  869.          value would be 0 and it would not affect the outcome.)
  870.      }
  871.      move pointer to next note in row (ie increment 4 bytes)
  872. }
  873.  
  874. This is your main inner loop and the part that needs to be optimized.  So 
  875. make sure you can try and get it as fast as possible.
  876.  
  877. *NOTE - setfrequency in this example is being passed amiga values, and should
  878.     convert it to a relevant hardware value.
  879.  
  880. ┌──────────────────────────────────────────────┐
  881. │ ░▒▓ 3.5 Period Frequencies and Fine Tune ▓▒░ │
  882. └──────────────────────────────────────────────┘
  883.  
  884. The formula for converting amiga period value to hz, is accomplished using
  885. ONE of the following formulas.  Why there are 2 will be explained shortly.
  886. You are going to have to convert amiga frequencies to some sort of speed or
  887. frequency factor for YOUR sound card, so this part will show you how.
  888.  
  889. PAL:   7093789.2 / (amigaval * 2)
  890. NSTC:  7159090.5 / (amigaval * 2)
  891.  
  892. Say if we wanted to find the value in hz for middle note C-2.  Looking up
  893. the amiga table we see the value for C-2 is 428 (see table below).
  894.  
  895. therefore:
  896.  
  897. PAL:   7093789.2 / (428 * 2) = 8287.14hz
  898. NSTC:  7159090.5 / (428 * 2) = 8363.42hz
  899.  
  900. A quick explanation on PAL and NSTC.  The amiga used to time its mods by
  901. sitting their interrupt handlers on the vertical retrace of the video screen
  902. so the period values they used in the tables are the amount of data to send
  903. to the amiga sound chip between interrupts, therefore changing the speed of
  904. data sent and the pitch of the note.  Pretty stupid system huh.  But I suppose
  905. back then they just wanted it to work and werent too worried about the future.
  906.   Trackers like FastTracker 2 are taking a step in the right direction by
  907. using linear frequency tables.. ST3 took a step backwards by trying to base
  908. s3m on the mod format.  This is MUSIC we are talking about not computer
  909. hardware.
  910.  
  911. Which should I use? you are asking.  Well I think the NSTC is the most widely
  912. accepted and used value, but it does not really matter.  The only difference
  913. you might hear is a SLIGHT change in pitch, like about one fine tune out
  914. say.  Inertia Play has a switch that lets you choose one or the other.  Try
  915. flicking between the 2 while a song is playing to see what it is like.
  916.  
  917. Here is a period table.  This is straight out of protracker so it is bugfree,
  918. other tables you might see in like gusplay by cascada have bugs in it.  Don't
  919. use it unless you can fix it.  (ie the bug is about F-2 with finetune -3 or
  920. so.. FastTracker 1 has the bug try it out.)
  921.  
  922. mt_PeriodTable
  923. ; Tuning 0, Normal
  924.     dc.w 856,808,762,720,678,640,604,570,538,508,480,453 ; C-1 to B-1
  925.     dc.w 428,404,381,360,339,320,302,285,269,254,240,226 ; C-2 to B-2
  926.     dc.w 214,202,190,180,170,160,151,143,135,127,120,113 ; C-3 to B-3
  927. ; Tuning 1
  928.     dc.w 850,802,757,715,674,637,601,567,535,505,477,450 ; same as above
  929.     dc.w 425,401,379,357,337,318,300,284,268,253,239,225 ; but with 
  930.     dc.w 213,201,189,179,169,159,150,142,134,126,119,113 ; finetune +1
  931. ; Tuning 2
  932.     dc.w 844,796,752,709,670,632,597,563,532,502,474,447 ; etc, 
  933.     dc.w 422,398,376,355,335,316,298,282,266,251,237,224 ; finetune +2
  934.     dc.w 211,199,188,177,167,158,149,141,133,125,118,112
  935. ; Tuning 3
  936.     dc.w 838,791,746,704,665,628,592,559,528,498,470,444
  937.     dc.w 419,395,373,352,332,314,296,280,264,249,235,222
  938.     dc.w 209,198,187,176,166,157,148,140,132,125,118,111
  939. ; Tuning 4
  940.     dc.w 832,785,741,699,660,623,588,555,524,495,467,441
  941.     dc.w 416,392,370,350,330,312,294,278,262,247,233,220
  942.     dc.w 208,196,185,175,165,156,147,139,131,124,117,110
  943. ; Tuning 5
  944.     dc.w 826,779,736,694,655,619,584,551,520,491,463,437
  945.     dc.w 413,390,368,347,328,309,292,276,260,245,232,219
  946.     dc.w 206,195,184,174,164,155,146,138,130,123,116,109
  947. ; Tuning 6
  948.     dc.w 820,774,730,689,651,614,580,547,516,487,460,434
  949.     dc.w 410,387,365,345,325,307,290,274,258,244,230,217
  950.     dc.w 205,193,183,172,163,154,145,137,129,122,115,109
  951. ; Tuning 7
  952.     dc.w 814,768,725,684,646,610,575,543,513,484,457,431
  953.     dc.w 407,384,363,342,323,305,288,272,256,242,228,216
  954.     dc.w 204,192,181,171,161,152,144,136,128,121,114,108
  955. ; Tuning -8
  956.     dc.w 907,856,808,762,720,678,640,604,570,538,508,480
  957.     dc.w 453,428,404,381,360,339,320,302,285,269,254,240
  958.     dc.w 226,214,202,190,180,170,160,151,143,135,127,120
  959. ; Tuning -7
  960.     dc.w 900,850,802,757,715,675,636,601,567,535,505,477
  961.     dc.w 450,425,401,379,357,337,318,300,284,268,253,238
  962.     dc.w 225,212,200,189,179,169,159,150,142,134,126,119
  963. ; Tuning -6
  964.     dc.w 894,844,796,752,709,670,632,597,563,532,502,474
  965.     dc.w 447,422,398,376,355,335,316,298,282,266,251,237
  966.     dc.w 223,211,199,188,177,167,158,149,141,133,125,118
  967. ; Tuning -5
  968.     dc.w 887,838,791,746,704,665,628,592,559,528,498,470
  969.     dc.w 444,419,395,373,352,332,314,296,280,264,249,235
  970.     dc.w 222,209,198,187,176,166,157,148,140,132,125,118
  971. ; Tuning -4
  972.     dc.w 881,832,785,741,699,660,623,588,555,524,494,467
  973.     dc.w 441,416,392,370,350,330,312,294,278,262,247,233
  974.     dc.w 220,208,196,185,175,165,156,147,139,131,123,117
  975. ; Tuning -3
  976.     dc.w 875,826,779,736,694,655,619,584,551,520,491,463
  977.     dc.w 437,413,390,368,347,328,309,292,276,260,245,232
  978.     dc.w 219,206,195,184,174,164,155,146,138,130,123,116
  979. ; Tuning -2
  980.     dc.w 868,820,774,730,689,651,614,580,547,516,487,460
  981.     dc.w 434,410,387,365,345,325,307,290,274,258,244,230
  982.     dc.w 217,205,193,183,172,163,154,145,137,129,122,115
  983. ; Tuning -1
  984.     dc.w 862,814,768,725,684,646,610,575,543,513,484,457
  985.     dc.w 431,407,384,363,342,323,305,288,272,256,242,228
  986.     dc.w 216,203,192,181,171,161,152,144,136,128,121,114
  987.  
  988. * I personally used a sorted form of this table, that orders all the notes
  989.   from C-1 with -8 finetune, then goes up through all the finetunes to B-3
  990.   with finetune +7.  Makes things a lot easier I find.
  991.  
  992. ┌─────────────────────────────────────────────┐
  993. │ ░▒▓ 3.5.1 What do I do with this table? ▓▒░ │
  994. └─────────────────────────────────────────────┘
  995. I pondered this one myself for a bit when I first started.  It would be nice
  996. if you could just store in the amiga values as your notes, then give them to
  997. your formula to use, and not even use a table to lookup amiga values.  
  998. But there lies a problem.  Namely finetune and arpeggio.  If you have the
  999. amiga values stored as notes, then you will have no idea how much to fine
  1000. tune according to the note you are on.  If it was a linear table it would be
  1001. fine (you would just say 'finetune = 2, so add 2 to the pitch'), but as it
  1002. is actually a logarithmic table adding 2 on a C1 note gives a totally
  1003. different tone to adding 2 on a C3 note.
  1004.  
  1005. Forget storing the actual amiga periods as your notes, in your loader convert
  1006. the periods to note numbers (see section 2.6.1), so you can use it to look
  1007. up the period table later when the tune is playing.
  1008.  
  1009. If you are still a bit confused this is how it is done.
  1010.  
  1011. - Loading the pattern data, I looked up the amiga value loaded and gave it
  1012.   a number from 8 to 288.  (36 notes, multiply it by 8 for finetunes between,
  1013.   remember each note is 8 finetunes apart, so it equals 288.)
  1014. - start at 8 (C-1) because there are going to be 8 finetunes below C-1.
  1015. - finish at 288 (B-3), and rememer there is going to be 7 finetunes above
  1016.   it.
  1017.  
  1018. - You get this value by reading in the amiga value from the file, and scan
  1019.   through the period table (given above) until you find a match.
  1020.   (some trackers don't save the right numbers so I used a check if the number
  1021.    was between -2 to +2 from the actual value).
  1022.   Once you find the corresponding value, store the note as your (counter*8) 
  1023.   where counter was the value you were incrementing as you went through the
  1024.   table.
  1025. - Now the pattern data is loaded up with a nice linear set of notes.
  1026.  
  1027. - when you actually play it just use your linear value as an index to look
  1028.   up the amiga table again to get the correct amiga period value.
  1029.  
  1030. ok here's how I did it.
  1031. -----------------------
  1032. period = ((byte0 & 0xF) << 8) + byte1;   // read in the value from file
  1033.  
  1034. current -> period = -1;                  // default value to -1, or 'nothing'
  1035. for (count2=1;count2<37; count2++) {     // start the search
  1036.      if (period > freqtab[count2*8]-2 && period < freqtab[count2*8]+2 )
  1037.       current -> period = count2*8;  // if found store the counter as
  1038. }                                        // the index for the note.
  1039.  
  1040. If we went through the whole table and didnt find the value, then it is
  1041. assumed there is no note, and it stays at -1.
  1042.  
  1043. ┌────────────────────────────────────┐
  1044. │ ░▒▓ 3.5.2 Gravis UltraSound :) ▓▒░ │
  1045. └────────────────────────────────────┘
  1046.  
  1047. How to change to a GUS frequency???  Well you should find this sort of stuff
  1048. yourself but because im gus biased ill talk a bit about it :)
  1049.  
  1050. Assuming 44khz mixing rate:
  1051. first :      hz = 7159090.5 / ( amigaval * 2 );
  1052.  next : gusfreq = ( hz / 44100) * 1024;
  1053.  
  1054. simple huh.. the 44100 would change to whatever mixing rate you are using
  1055. depending on the amount of voices.  Ie say I use 20 voices so looking up
  1056. this table...
  1057.  
  1058.    Frequency   Active Voices
  1059.     44100          14 or lower
  1060.     41160          15
  1061.     38587          16
  1062.     36317          17
  1063.     34300          18
  1064.     32494          19
  1065.     30870          20
  1066.     29400          21
  1067.     28063          22
  1068.     26843          23
  1069.     25725          24
  1070.     24696          25
  1071.     23746          26
  1072.     22866          27
  1073.     22050          28
  1074.     21289          29
  1075.     20580          30
  1076.     19916          31
  1077.     19293          32
  1078.  
  1079. ..My formula becomes gusfreq = ( hz / 30870 ) * 1024;
  1080. BUT: with a bit of mathematical optimization I reduced this formula down to:
  1081.  
  1082. hz = 7159090.50 / (freq * 2)             gusfreq = ( hz / 30870 ) * 1024
  1083.    = 3579545.25 / freq                           = hz / 30.14648438
  1084.  
  1085. now: gusfreq = ( 3579545.25 / freq ) / 30.14648438
  1086.          = 118738.3894 / freq
  1087.  
  1088. #define GUSfreq(x)      118738/x
  1089. where x is the amiga value found in our period table.. saves a lot of 
  1090. calculation huh! (cuts 4 divs/muls down to 1 div)
  1091.  
  1092. ok ok.. I know you are too lazy to work out 44.1khz, so it 
  1093. is 83117 / amigafreq.
  1094.  
  1095. ┌────────────────────┐
  1096. │ ░▒▓ 3.6 Volume ▓▒░ │
  1097. └────────────────────┘
  1098. Handling volumes is one of the simplest parts of coding your player.  It
  1099. is just a matter of looking up a table or adjusting the percentage of
  1100. the sample to be mixed into the final output.
  1101.  
  1102. Remember there are actually 65 volume settings, just when you thought there
  1103. were only 64 (040h) :).  0 is included which is absolutely no volume, and 64
  1104. is full volume.
  1105.  
  1106. For gus users this is one of the best volume tables I have found anywhere.
  1107. I have about 5 volume tables and this one is the one I use, it is quite loud
  1108. but not so loud to cause bad clipping.  Others I found are too soft.
  1109.  
  1110. word GUSvol[] = {
  1111.     0x1500,
  1112.     0x9300,0xA900,0xB400,0xBC00,0xC180,0xC580,0xC980,0xCD80,
  1113.     0xCF40,0xD240,0xD440,0xD640,0xD840,0xDA40,0xDC40,0xDE40,
  1114.     0xDEF0,0xDFA0,0xE1A0,0xE2A0,0xE3A0,0xE4A0,0xE5A0,0xE6A0,
  1115.     0xE7A0,0xE8A0,0xE9A0,0xEAA0,0xEBA0,0xECA0,0xEDA0,0xEEA0,
  1116.     0xEEF0,0xEFE0,0xEF60,0xF1E0,0xF160,0xF1E0,0xF260,0xF2E0,
  1117.     0xF360,0xF3E0,0xF460,0xF4E0,0xF560,0xF5E0,0xF660,0xF6E0,
  1118.     0xF760,0xF7E0,0xF860,0xF8E0,0xF960,0xF9E0,0xFA60,0xFAF0,
  1119.     0xFB70,0xFBF0,0xFC70,0xFCF0,0xFD70,0xFD90,0xFDB0,0xFDD0
  1120. };
  1121.  
  1122.  
  1123. ┌────────────────────────────────────────────────────────────────────────────┐
  1124. │                           ░▒▓  : SECTION 4 :  ▓▒░                          │
  1125. │                           ░▒▓  Miscellaneous  ▓▒░                          │
  1126. └────────────────────────────────────────────────────────────────────────────┘
  1127.  
  1128. This section describes some of the little things that should be taken note of
  1129. when writing a mod player, but are VERY important.
  1130.  
  1131. ┌─────────────────────────────────────────────────────────────┐
  1132. │ ░▒▓ 4.1 Notes Without Instrument Numbers or Frequencies ▓▒░ │ *IMPORTANT*
  1133. └─────────────────────────────────────────────────────────────┘
  1134. This subsection is just about the most important of this whole section.
  1135. Sometimes a composer will some seemingly strange methods to write a tune,
  1136. i.e. leaving an instrument number off, or putting an instrument number but
  1137. with no note!  This part describes how to combat this.
  1138.  
  1139. NO INSTRUMENT NUMBER:
  1140. ---------------------
  1141. C-2 01 C10
  1142. D-2 00 301 <- note no instrument number
  1143. --- 00 300
  1144.  
  1145. You will notice, on the porta to note that the composer has left off the 
  1146. instrument number.  Also notice that the previous note had the volume set
  1147. to 10.  Leaving off an instrument number causes the volume to stay as it is,
  1148. and so the note slides, but still stays at volume 10.
  1149.  
  1150. NO PERIOD VALUE OR NOTE:
  1151. ------------------------
  1152. C-1 01 A07
  1153. --- 01 A07 <- no period value (note), but there are instrument numbers
  1154. --- 01 A07
  1155. --- 01 A07
  1156.  
  1157. What this does is reset the volume on every note, and slides the volume down
  1158. on every note too.. This gives a stuttering effect that is commonly used.
  1159. It reinforces the last part (no instrument number), that if there is an
  1160. instrument number, then the volume is reset to the sample's default volume.
  1161.  
  1162. NOTE BUT NOTHING ELSE:
  1163. ----------------------
  1164. C-1 01 000
  1165. D-1 00 000
  1166. E-1 00 000
  1167.  
  1168. This means the sample is reset to its starting position, on all 3 notes.
  1169.  
  1170. CONCLUSION:
  1171. -----------
  1172.  
  1173. - ONLY RESET VOLUME IF THERE IS AN INSTRUMENT NUMBER
  1174. - ONLY RESET PITCH IF THERE IS A PERIOD VALUE/NOTE
  1175. - ONLY RESET SAMPLE IF THERE IS A PERIOD VALUE/NOTE (and no effect 3xy, 5xy 
  1176.                                or EDx)
  1177.  
  1178.  
  1179. ┌────────────────────────────────────────────────────────────────────────────┐
  1180. │                           ░▒▓  : SECTION 5 :  ▓▒░                          │
  1181. │                           ░▒▓     Effects     ▓▒░                          │
  1182. └────────────────────────────────────────────────────────────────────────────┘
  1183.  
  1184. This part of the document is one of the most sorely needed, it actually tells
  1185. you HOW to code the effect, not just some vague reference on it and a basic
  1186. explanation like I have seen in so many other docs.
  1187.  
  1188. TERMINOLOGY:
  1189. ============
  1190. Beside each effect, there are the 2 Y/N boxes.. these are;
  1191.  
  1192.        T0 : (TICK 0) This means the effect is updated or taken care of at the 
  1193.         start of the row, or when the row is first encountered.
  1194. INBETWEEN : This means the effect is updated on the other (speed-1) ticks 
  1195.         that lie inbetween rows.
  1196.  
  1197. When coding your player, go for effect Cxy first.  It is the easiest and most
  1198. substantial effect to enable.  It will even make your tune resemble its
  1199. normal self :).  Then go for effect Fxy (set speed).
  1200.  
  1201. ┌───────────────────────────────────┐
  1202. │ ░▒▓ 5.1 Effect 0xy (Arpeggio) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1203. └───────────────────────────────────┘
  1204. This effect alternates the pitch rapidly to simulate a chord.  It usually
  1205. sounds very grating or harsh so it isnt used much except for chip tunes.
  1206.  
  1207. EG: 
  1208. C-2 01 047 (I want to add to the pitch by 4 half notes then 7)
  1209.  
  1210. Range: x = 1st semitone to add to note (0h-Fh)
  1211.        y = 2nd semitone to add to note (0h-Fh)
  1212.  
  1213. so the effect 047 would generate a major, while effect 037 causes a minor.
  1214.  
  1215. This is a tick based effect:
  1216. Tick 0 Do nothing,
  1217. Tick 1 you add the x arg, 
  1218. Tick 2 you add the y arg,
  1219. Tick 3 you reset the frequency
  1220. .... go back and do from tick 1 until we reach the next row
  1221.  
  1222. You notice if SPEED is 1, then there will be no arpeggiation because there
  1223. are no ticks inbetween.  If SPEED is 2, then only the x arg is taken into
  1224. account.
  1225. Each note is 8 fine tunes apart, so use your finetune table to calculate the
  1226. next row down if you like, or use a special arpeggio table to find the values
  1227. to add.
  1228.  
  1229. It is done something like this:
  1230. - increment arpcounter by 1
  1231. - if arpcounter > 2 arpcounter = 0
  1232. - if arpcounter = 0 set the frequency to the normal value
  1233. - if arpcounter = 1 set the frequency to the normal value + x # of finetunes
  1234. - if arpcounter = 2 set the frequency to the normal value + y # of finetunes
  1235.  
  1236. ┌───────────────────────────────────┐
  1237. │ ░▒▓ 5.2 Effect 1xy (Porta Up) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1238. └───────────────────────────────────┘
  1239. This effect causes a pitch slide that goes up.
  1240.  
  1241. EG: 
  1242. C-2 01 104 (I want to slide the frequency up 4 amiga values every tick)
  1243. --- 00 104 (slide againt 4 values every tick)
  1244.  
  1245. Range: xy = 00h-FFh
  1246.  
  1247. You do this by resetting the frequency every tick, EXCEPT for the first one.
  1248. The amount to slide by is the value given in EFFECT_PARAMETER
  1249. You add the value to the AMIGA value of the frequency.
  1250.  
  1251. Tick 0 Do nothing.
  1252. Tick 1 add EFFECT_PARAMETER to the amiga frequency, and set it.
  1253. Tick 2 add EFFECT_PARAMETER to the amiga frequency, and set it.
  1254. Tick 3 add EFFECT_PARAMETER to the amiga frequency, and set it.
  1255. .... keep going until end of note
  1256.  
  1257. Remember B-3 is the highest note you can use, there is no law against sliding
  1258. above it but it is not standard (some mods might be written thinking that 
  1259. the porta WILL stop at B-3, so be carefull).  Personally I stop at 54, or 
  1260. approximately B-5.
  1261.  
  1262. ┌─────────────────────────────────────┐
  1263. │ ░▒▓ 5.3 Effect 2xy (Porta Down) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1264. └─────────────────────────────────────┘
  1265. This effect causes a pitch slide that goes down.
  1266.  
  1267. EG: 
  1268. C-2 01 204 (I want to slide the frequency down 4 amiga values every tick)
  1269. --- 00 204 (slide again 4 amiga values every tick)
  1270.  
  1271. Range: xy = 00h-FFh
  1272.  
  1273. You do this by resetting the frequency every tick, EXCEPT for the first one.
  1274. The amount to slide by is the amound given in EFFECT_PARAMETER.
  1275. You subtract the value from the AMIGA value of the frequency.
  1276.  
  1277. Tick 0 Do nothing.
  1278. Tick 1 subtract EFFECT_PARAMETER from the frequency, and set it.
  1279. Tick 2 subtract EFFECT_PARAMETER from the frequency, and set it.
  1280. Tick 3 subtract EFFECT_PARAMETER from the frequency, and set it.
  1281. .... keep going until end of note
  1282.  
  1283. Be careful you don't slide too low.  Going below C-1 is non standard, and 
  1284. going below a frequency of 1 could cause horrible side effects :)
  1285.  
  1286. ┌────────────────────────────────────────┐
  1287. │ ░▒▓ 5.4 Effect 3xy (Porta To Note) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [Y]  
  1288. └────────────────────────────────────────┘
  1289. This effect causes the pitch to slide towards the note specified.
  1290. If there is no note specified it slides towards the last note specified in
  1291. the Porta to Note effect.
  1292. If no parameter use the last porta speed used for that channel.
  1293.  
  1294. EG: 
  1295. C-2 01 000 
  1296. D-2 01 301 (I want to set D-2 as the note to slide towards, and with a speed
  1297. --- 00 300  of 1, then I just want to keep it sliding to D-2, and you already
  1298. --- 00 300  know the speed so I wont bother telling you again)
  1299. --- 00 300
  1300.  
  1301. Range: xy = 00h-FFh
  1302.  
  1303. This effect can be buggy at first, but not too hard.
  1304. on TICK 0:
  1305. - If there is an argument given to the effect, then you must record that as 
  1306.   PORTA_SPEED[channel]. (You need to remember all 4-8 channels worth of porta 
  1307.   information - I have them as a global array)
  1308. - If there is a note given, then you must store that as 
  1309.   NOTE_TO_PORTA_TO[channel].
  1310. - But don't slide here, just like the other porta effects.
  1311. - also, don't reset the note like you would normally if there was a frequency
  1312.   given (i.e. the D-2 in our example)
  1313.  
  1314. On OTHER ticks:
  1315. - Subtract or add PORTA_SPEED to the frequency (in AMIGA units), and set it.
  1316.   Subtract or add depending on if the current frequency is smaller or larger
  1317.   than NOTE_TO_PORTA_TO.
  1318.  
  1319. ┌──────────────────────────────────┐
  1320. │ ░▒▓ 5.5 Effect 4xy (Vibrato) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1321. └──────────────────────────────────┘
  1322. This effect causes the pitch to waver up and down around the base note.
  1323. If no parameter use the last vibrato parameters used for that channel.
  1324.  
  1325. EG:
  1326. D-2 01 4A2 <- I want to vibrato the note D-2 with speed of A, and depth of 2
  1327. --- 00 400 <- Keep vibrating at A2 
  1328. --- 00 4B3 <- now change to B3
  1329. --- 00 400 <- Continue vibrating at B3
  1330.  
  1331. Range: x = speed to vibrate at (0h-Fh)
  1332.        y = depth of vibrato (0h-Fh)
  1333.  
  1334. This is simply a case of getting a sine table (the default wavecontrol - see
  1335. section 5.20 for other vibrato wavecontrols), and following along it 
  1336. adjusting the frequency by adding or subtracting the value found according to
  1337. the the position of the table, which is incremented by VIBRATO_SPEED. 
  1338. (ie you skip through the sine table VIBRATO_SPEED positions every tick)
  1339.  
  1340. On TICK 0 the 2 vibrato values (position and neg flag) should be cleared to 0 
  1341. if a new note is played, so we restart the waveform at the start again.
  1342.  
  1343. Positioning vibrato pointer
  1344. ----------------------------
  1345. There are 32 positions in the sine table.  You want to ADD the values in
  1346. the sinetable to the frequency, then once it gets to the end, you want to
  1347. go back and SUBTRACT the same values from the frequency.  This gives a nice
  1348. wave.   The reason we do this is because the sine table only contains half
  1349. a wave (ie. a bump - see diagram).  Running through it once then turning it
  1350. upside down by negating it would produce a smooth running wave which
  1351. oscillates up and down..
  1352.  
  1353.     +1|       ****        /At this point we subtract from frequency                 
  1354.       |    ***    ***    /
  1355. Current 0 |****          ***|****          ****   -> time
  1356.       |                 |    ***    ***
  1357.     -1|                 |       ****
  1358.                 32
  1359.  
  1360. So once your VIBRATO_POS has gone past 32, then subtract 32 from it so it 
  1361. starts at a respectable place at the beginning again. THEN change the 
  1362. negation flag (ie flag: 0 for add values, 1 for subtract values).
  1363.  
  1364. Sine Table
  1365. ----------
  1366. This is the sine table used by Protracker.  If a player calls itself
  1367. fully protracker compatible, it really should be using this table.  GUSPlay
  1368. by Cascada uses a table that is slightly different, but I cant hear the
  1369. difference :)
  1370.  
  1371.        0, 24, 49, 74, 97,120,141,161,
  1372.      180,197,212,224,235,244,250,253,
  1373.      255,253,250,244,235,224,212,197,
  1374.      180,161,141,120, 97, 74, 49, 24
  1375.  
  1376. Calculating depth
  1377. -----------------
  1378. To calculate the amount or depth of the vibrato, you multiply the siner value
  1379. by the effect parameter y, THEN you divide it by 128.  Remember the divide
  1380. by 128 (or shift right 7bits) must be implemented or you'll have some HUGE
  1381. vibrato :)
  1382.  
  1383. Setting the frequency.
  1384. ----------------------
  1385. - Work out the size of the delta (delta means how much to add or subtract)
  1386. - ie. delta = vibrato_depth[CHANNEL] * sine_table[vibrato_pos[CHANNEL] / 128
  1387. -     if vibrato_negflag[CHANNEL] = 0, then SetFrequency(freq[CHANNEL]+delta)
  1388. -   else SetFrequency(freq[CHANNEL] - delta)
  1389.  
  1390. Example code.
  1391. -------------
  1392. For those interested this is how mine works, but I don't think it is 100%
  1393.  
  1394. if (effect == 0x4 || effect == 0x6) {
  1395.     // work out the delta
  1396.     vib = vibdep[track]*sintab[vibpos[track]] >> 7;     // >> 7 = div 128
  1397.     
  1398.     // add the delta to the track's frequency if neg flag = 0
  1399.     // subtract the delta to the track's frequency if neg flag = 1
  1400.     if (vibneg[track] == 0) GUSSetFreq(track, GUSfreq(freq[track]+vib));
  1401.     else                    GUSSetFreq(track, GUSfreq(freq[track]-vib));
  1402.  
  1403.     vibpos[track]+=vibspe[track];           // increment vib position
  1404.     
  1405.     if (vibpos[track] > 31) {
  1406.         vibpos[track] -=32;                      // jump back to start
  1407.         if (vibneg[track]==0) vibneg[track] = 1; // change neg flag
  1408.         else vibneg[track]=0;
  1409.     }
  1410. }
  1411.  
  1412. ┌────────────────────────────────────────────┐
  1413. │ ░▒▓ 5.6 Effect 5xy (Porta + Vol Slide) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1414. └────────────────────────────────────────────┘
  1415. This is a combination of Porta to Note (3xy), and volume slide (Axy).
  1416. The parameter does not affect the porta, only the volume.
  1417. If no parameter use the last porta to note parameter used for that channel.
  1418.  
  1419. EG:
  1420. C-1 01 000
  1421. D-1 01 301  <- start porta to note using speed of 3.
  1422. --- 00 501  <- from here on keep doing porta, but slide volume down 1 as well.
  1423. --- 00 501
  1424. --- 00 501
  1425.  
  1426. Range: x = amount to slide volume up by or (0h-Fh)
  1427.        y = amount to slide volume down by. (0h-Fh)
  1428.  
  1429. This is exactly what it means, just do a 3xy first, then do a volume slide.
  1430. The arguments only refer to the volume slide though and do not affect the
  1431. porta.  The porta is carried on from the last porta to note.
  1432. So when you code your effect routine, it's like
  1433.  
  1434. if (effect = 03h OR effect = 05h) DO_PORTA_TO_NOTE
  1435. if (effect = 0Ah OR effect = 05h) DO_VOLUME_SLIDE
  1436.  
  1437. kill 2 birds with 1 stone!
  1438.  
  1439. ┌────────────────────────────────────────────┐
  1440. │ ░▒▓ 5.7 Effect 6xy (Vibrato+Vol Slide) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1441. └────────────────────────────────────────────┘
  1442. This is a combination of Vibrato (4xy), and volume slide (Axy).
  1443. The parameter does not affect the vibrato, only the volume.
  1444. If no parameter use the vibrato parameters used for that channel.
  1445.  
  1446. EG:
  1447. C-1 01 4A2  <- start Vibrato with speed 0Ah, and depth 2.
  1448. --- 00 601  <- from here on keep doing vibrato, but slide volume down 1 as 
  1449. --- 00 601     well.
  1450. --- 00 601
  1451.  
  1452. Range: x = amount to slide volume up by or, (0h-Fh)
  1453.        y = amount to slide volume down by. (0h-Fh)
  1454.  
  1455. This is exactly like effect 5xy, but just do a 4xy first, then do a volume 
  1456. slide.
  1457. The arguments only refer to the volume slide though and do not affect the
  1458. vibrato.  The Vibrato is carried on from the Vibrato.
  1459. So when you code your effect routine, it's like
  1460.  
  1461. if (effect = 04h OR effect = 06h) DO_PORTA_TO_NOTE
  1462. if (effect = 0Ah OR effect = 06h) DO_VOLUME_SLIDE
  1463.  
  1464. kill 2 birds with 1 stone again! (hrmm thats 4 birds now :)
  1465.  
  1466. ┌──────────────────────────────────┐
  1467. │ ░▒▓ 5.8 Effect 7xy (Tremolo) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1468. └──────────────────────────────────┘
  1469. This effect causes the volume to oscillate up and down in a fluctuating style
  1470. around the current volume, like vibrato but affecting volume not pitch.
  1471. If no parameter use the last tremolo parameter used for that channel.
  1472.  
  1473. EG:
  1474. C-2 01 772 (I want to vibrate the volume up and down using speed 7 & depth 2)
  1475. --- 00 700 (continue with the tremolo at 7,2)
  1476.  
  1477. Range: x = speed to vibrate volume at (0h-Fh)
  1478.        y = depth of tremolo (0h-Fh)
  1479.  
  1480. Seeing as this is a similar effect to vibrato, then we will use the same
  1481. tables as it does.  The only difference with tremolo is that you divide the
  1482. delta (or deviation) by 64 and not 128.  You also have to check for if the
  1483. volume goes over or under 0 and 64.
  1484. This means if the biggest value in the sine table 255 is divided by 64,
  1485. then the biggest deviation with depth parameter of 1 would only be 4, on its
  1486. peak.
  1487. You're probably asking, what if the volume of the channel is 64?  Well in
  1488. this case you would only hear the negative side of the tremolo, when the
  1489. volume dips down and then back to full.  Same for the vice versa case if
  1490. the volume is set to 0.
  1491.  
  1492. On TICK 0 the 2 tremolo values (position and neg flag) should be cleared to 0 
  1493. if a new note is played, so we restart the waveform at the start again.
  1494.  
  1495. This is how it works.
  1496. - Work out the size of the delta (delta means how much to add or subtract)
  1497. - ie. delta = tremolo_depth[CHANNEL] * sine_table[tremolo_pos[CHANNEL] / 64
  1498.       if tremolo_negflag[CHANNEL] = 0, then {
  1499.          check if volume[CHANNEL] + delta > 64 and clip delta accordingly
  1500.          SetVolume(volume[CHANNEL]+delta)
  1501.       }
  1502.       else {
  1503.          check if volume[CHANNEL] - delta < 0 and clip delta accordingly
  1504.          SetVolume(volume[CHANNEL] - delta)
  1505.       }
  1506. - increase tremolo_position pointer and set neg flag accordingly (For any 
  1507. more information check vibrato because they really are the same.  It is
  1508. explained in more detail, and the sine table mentioned is stored in there
  1509. also.)
  1510.  
  1511. ┌──────────────────────────────┐
  1512. │ ░▒▓ 5.9 Effect 8xy (Pan) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]  
  1513. └──────────────────────────────┘
  1514. This effect is non-Protracker, but is worth mentioning.  It was introduced
  1515. by Otto Chrons in DMP (dual mod player), and causes the left/right position 
  1516. of the current channel to be set to the position specified.  Hence Panning.
  1517.  
  1518. EG:
  1519. --- 00 800              (Set the position of the channel to the far left)
  1520.  
  1521. 00 = far left
  1522. 40 = middle
  1523. 80 = far right
  1524. A4 = surround *
  1525.  
  1526. (* Surround is usually achieved by having 2 copies of the sample, 1 inverted,
  1527.    and you play them at -exactly- the same time, with one of the pair panned
  1528.    fully left, and the other (the inverted one say) panned fully right.  This 
  1529.    will give a surround effect.  If you play both the samples in the same pan
  1530.    position they will cancel each other out.  Experiment with this in a
  1531.    tracker.  Using GoldWave(tm) you can invert a sample.
  1532.    As efffect 8xy is a channel command, you will have to in effect have 2
  1533.    channels (voices) ready for this channel, and make sure you set one
  1534.    voice to the full left, and the other inverted, and to the full left.
  1535.    You CAN have surround sound on a GUS.)
  1536.  
  1537. ┌─────────────────────────────────────────┐
  1538. │ ░▒▓ 5.10 Effect 9xy (Sample Offset) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1539. └─────────────────────────────────────────┘
  1540. This effect causes the note to start playing at an offset into the sample,
  1541. instead of just from the start.  It is used so that the beginning of a sample
  1542. is not played, but skipped.
  1543.  
  1544. EG:
  1545. C-2 01 942 (I want to start the note playing at 4200h bytes into the sample)
  1546.  
  1547. Range: xy = 00h-FFh
  1548.  
  1549. As seen in the example, the argument is the first 2 digits of a 4 digit
  1550. number (in hex) that the offset should take place from.
  1551.  
  1552. so SAMPLE_OFFSET = EFFECT_PARAMETER * 0100h
  1553.  
  1554. What you do to enable this effect is when you tell your soundcard or mixing
  1555. buffer the start of the sample, also add to it the value SAMPLE_OFFSET and
  1556. then play it.  Quite simple really.
  1557.  
  1558. Remember to check if the user set an offset that is larger than the sample!
  1559.  
  1560. ┌────────────────────────────────────────┐
  1561. │ ░▒▓ 5.11 Effect Axy (Volume Slide) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]
  1562. └────────────────────────────────────────┘
  1563. This effect causes the volume of the track to slide up or down.
  1564.  
  1565. EG:
  1566. A-2 01 A01  <- slide the volume down 1 * (speed-1) units
  1567. --- 00 A01  <- slide the volume down 1 * (speed-1) units
  1568. --- 00 A01  <- slide the volume down 1 * (speed-1) units
  1569. --- 00 A20  <- now slide the volume up 2 * (speed-1) units
  1570. --- 00 A20  <- slide the volume up 2 * (speed-1) units
  1571.  
  1572. Range: x = amount to slide volume up by or, (0h-Fh)
  1573.        y = amount to slide volume down by. (0h-Fh)
  1574.  
  1575. On this affect you either slide the volume up x, or down y, but not both.
  1576. This is a tick based effect so should be processed once a tick but not tick 0.
  1577. if x > 0 then slide volume up x
  1578. if y > 0 then slide volume down y
  1579. if x > 0 and y > 0 then do nothing.
  1580.  
  1581. On tick 0:
  1582. Take note of the volume slide, but do nothing
  1583.  
  1584. On other ticks:
  1585. if x > 0 then add x to volume[CHANNEL] and set the volume
  1586. if y > 0 then subtract y to volume[CHANNEL] and set the volume
  1587.  
  1588. * before setting the volume, make sure you havent slid past 0 or 64.
  1589.  
  1590. ┌───────────────────────────────────────────┐
  1591. │ ░▒▓ 5.12 Effect Bxy (Jump To Pattern) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1592. └───────────────────────────────────────────┘
  1593. This effect jumps to a specified channel (in hex)
  1594.  
  1595. EG:
  1596. --- 00 B10 (I want to jump to order 10h, or 16)
  1597.  
  1598. Range: xy = 00h-FFh
  1599.  
  1600. This effect is fairly simple, after the ticks for the note are finished, 
  1601. then reset the position of the order, starting at row 0 again.
  1602. Make sure you don't jump over the end of the song length, and if you do then
  1603. set it to the last order.
  1604.   
  1605. * if you increment your row after your PlayNote() function, then row should
  1606.   be set to -1, so it is 1 less than 0, then as the tick handler adds 1 to
  1607.   the row it is 0 again, and nothing is wrong.
  1608.  
  1609. ┌──────────────────────────────────────┐
  1610. │ ░▒▓ 5.13 Effect Cxy (Set Volume) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1611. └──────────────────────────────────────┘
  1612. This effect sets the volume of a channel.
  1613.  
  1614. EG:
  1615. C-2 01 C20 (I want to set the volume of the channel to 20h)
  1616.  
  1617. Range: xy = 00h-40h
  1618.  
  1619. This is about the easiest and first effect you should code.  It is just a
  1620. simple case of setting the tracks volume to the argument specified (in hex)
  1621. The volume cannot be set past 40h, and if it is then set it to 40h.
  1622. Only process this effect on tick 0, and likewise only set the volume on tick
  1623. 0.
  1624.  
  1625. ┌─────────────────────────────────────────┐
  1626. │ ░▒▓ 5.14 Effect Dxy (Pattern Break) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1627. └─────────────────────────────────────────┘
  1628. This effect breaks to the next pattern starting at the specified row.
  1629.  
  1630. EG:
  1631. --- 00 D32 (I want to break from this pattern and start at row 32h on the next
  1632.         pattern)
  1633.  
  1634. Range: xy = 00h-3Fh (0-63 decimal)
  1635.  
  1636. This effect is similair to effect Bxy or pattern jump.  You only jump to 
  1637. the next pattern though, and you start tracking again at the specified row.
  1638. The row should not be bigger than 63, and if it is take it as 0.
  1639. It works something like this:
  1640.   - increment order (only once, some mods have more than 1 pbreak on a row
  1641.               which could cause an increment order twice or more!)
  1642.   - set row to be x*10 + y. (we have to get the decimal value not the hex)
  1643.   
  1644. * if you increment your row after your PlayNote() function, then row should
  1645.   be set to (x*10+y -1), so it is 1 less, then as the tick handler adds 1 to
  1646.   to the row again, nothing is wrong.
  1647.  
  1648. ┌─────────────────────────────────────┐
  1649. │ ░▒▓ 5.15 Effect Fxy (Set Speed) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1650. └─────────────────────────────────────┘
  1651. This effect sets the speed of the song or the BPM.
  1652.  
  1653. EG:
  1654. --- 00 F07 (I want to set the speed of the song to 7 ticks a row)
  1655. --- 00 F7D (I want to set the bpm of the song to 125 or 7Dh)
  1656.  
  1657. Range: xy = 00h-1Fh for speed
  1658.        xy = 20h-FFh for BPM
  1659.  
  1660. This has 2 parts to it.  If the user specifies a parameter from 0 - 1Fh, then
  1661. it is just simply a case of setting your speed variable, otherwise you need
  1662. to set your bpm variable and reset the timer speed.  This is demonstrated in
  1663. section 3.2 on how to change the speed of the system timer according to 
  1664. beats per minute.
  1665.  
  1666. ┌──────────────────────────────────────┐
  1667. │ ░▒▓ 5.16 Effect E0x (Set Filter) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1668. └──────────────────────────────────────┘
  1669. This effect turns on or off the hardware filter (not applicable to most pc
  1670. sound cards)
  1671.  
  1672. EG:
  1673. --- 00 E01 (I want to turn the filter on)
  1674. --- 00 E00 (I want to turn the filter off)
  1675.  
  1676. Range: x = 0 to turn hardware filter off, 1 to turn it on (0-1)
  1677.  
  1678. There isnt much to say about this effect, except for that it is a hardware
  1679. function which was designed to turn on the amiga's filter.
  1680. If you wanted to you could try implementing this effect in the SBPro's h/w
  1681. filter.
  1682.  
  1683. ┌─────────────────────────────────────────┐
  1684. │ ░▒▓ 5.17 Effect E1x (Fine Porta Up) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1685. └─────────────────────────────────────────┘
  1686. This effect slides the pitch up by x amiga value's per row.
  1687.  
  1688. EG:
  1689. C-2 01 E11 (I want to start at note C-2, and move pitch up one amiga value)
  1690. --- 00 E11 (keep sliding up...)
  1691. --- 00 E11
  1692.  
  1693. Range: x= amount to slide up by. (0h-Fh)
  1694.  
  1695. This effect is only processed once per row, on tick 0, and it is as simple
  1696. as just subtracting x from the current channel's frequency. (remember you
  1697. subtract to raise the pitch.)  You don't subtract any finetunes or anything,
  1698. just do a straight subtraction of x from the amigaval.
  1699.  
  1700. ┌───────────────────────────────────────────┐
  1701. │ ░▒▓ 5.18 Effect E2x (Fine Porta Down) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1702. └───────────────────────────────────────────┘
  1703. This effect slides the pitch down by x amiga value's per row.
  1704.  
  1705. EG:
  1706. C-2 01 E21 (I want to start at note C-2, and move pitch down one amiga value)
  1707. --- 00 E21 (keep sliding down...)
  1708. --- 00 E21
  1709.  
  1710. Range: x = amount to slide pitch down by. (0h-Fh)
  1711.  
  1712. This is identical to effect E2x, except but you add to the amigaval of the 
  1713. channel by x, and don't subtract.
  1714.  
  1715. ┌────────────────────────────────────────────┐
  1716. │ ░▒▓ 5.19 Effect E3x (Glissando Contrl) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]  
  1717. └────────────────────────────────────────────┘
  1718. This effect causes a change in the effect 3xy (porta to note).  It toggles
  1719. whether to do a smooth slide or whether to slide in jumps of semitones.
  1720.  
  1721. EG:
  1722. --- 00 E31 (I want to turn on Glissando and have portas slide in semitones)
  1723. --- 00 E30 (I want to turn off Glissando and have portas slide smoothly)
  1724.  
  1725. Range: x = 0 to turn off glissando, 1 to turn it on (0-1)
  1726.  
  1727. By default this value should be set as 0, or doing a smooth slide.  It is
  1728. achieved by adding or subtracting the desired porta value too or from the
  1729. amiga value in effect 3xy, but you already knew that :).  
  1730. With glissando turned on it is a different story.  It is just simply a case
  1731. of setting the frequency to the next highest semitone (or 8 finetune values)
  1732. if you are sliding the pitch up, and vice versa for going down.
  1733. To implement this just keep a gliss flag and check it while doing your porta
  1734. effect in your UpdateEffect function.
  1735.  
  1736. ┌────────────────────────────────────────────┐
  1737. │ ░▒▓ 5.20 Effect E4x (Vibrato Waveform) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1738. └────────────────────────────────────────────┘
  1739. This effect set the waveform for the vibrato command to follow.
  1740.  
  1741. EG:
  1742. --- 00 E42 (I want to select the squarewave function for the vibrato command)
  1743. --- 00 E40 (I want to select the default sinewave for the vibrato command)
  1744.  
  1745. Range: x = vibrato function to select (0-7)
  1746.  
  1747. The following values of x select its corresponding vibrato function
  1748. x=0 : Set sine wave  (default)
  1749. x=1 : Set Ramp Down  |\|\|\     _   _
  1750. x=2 : Set Squarewave         |_| |_| |_
  1751. x=3 : Set Random     (anywhere)
  1752. x=4 : don't retrig Sine waveform
  1753. x=5 : don't retrig RampDown waveform
  1754. x=6 : don't retrig Squarewave waveform
  1755. x=7 : don't retrig random waveform
  1756.  
  1757. - Sine wave is covered in the vibrato section (5.5), just apply a sine wave
  1758.   to the frequency.
  1759. - Square wave is simply subtracting and adding the VIB_DEPTH*256
  1760.   (then divided by 128) to the current frequency, alternating the
  1761.   add/subtract every VIB_SPEED number of ticks.
  1762. - retrig waveform means that you start the vibrato waveform from position 0
  1763.   everytime a new note is played.  If you have set the wave control flag to
  1764.   4 or more, then the waveform is not restarted, and just continues from the
  1765.   previous position in the vibrato waveform.
  1766.  
  1767. ┌────────────────────────────────────────┐
  1768. │ ░▒▓ 5.21 Effect E5x (Set Finetune) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1769. └────────────────────────────────────────┘
  1770. This effect sets the finetune on a selected instrument.
  1771.  
  1772. EG:
  1773. --- 01 E5F (I want to set the finetune of instrument 1 to -1)
  1774.  
  1775. Range: x = value of finetune to set (0h-0Fh)
  1776.  
  1777. if the value is > 7, just subtract 16 from it to get the signed value.
  1778. (ie. 0-7 = 0-7, and 8-15 = -8 to -1)
  1779. This effect is really easy, and I don't know why more players support it,
  1780. apart from it being a useless effect :).
  1781. To implement it, just
  1782. - check the instrument number
  1783. - get the finetune value in the effect
  1784. - set the finetune for that instrument.
  1785.  
  1786. ┌────────────────────────────────────────┐
  1787. │ ░▒▓ 5.22 Effect E6x (Pattern Loop) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1788. └────────────────────────────────────────┘
  1789. This effect allows the user to loop a part of a pattern x number of times.
  1790.  
  1791. EG:
  1792. C-2 01 E60 (I want to set the loop start at this point)
  1793. --- 00 000
  1794. --- 00 E64 (I want to loop back to the starting point 4 times)
  1795.  
  1796. Range: x=marks loop starting point, or sets the number of times to loop to 
  1797.      the starting point (0h-0Fh)
  1798.  
  1799. This effect is done in the following fashion.
  1800. - If parameter x = 0, note down the row number
  1801. - if parameter x > 0, then
  1802.     - if PATTERN_LOOP = 0, then set PATTERN_LOOP = x
  1803.      else PATTERN_LOOP = PATTERN_LOOP -1
  1804.     - if PATTERN_LOOP > 0 row = stored row number.   (if we are still looping
  1805.                                   then jump back)
  1806.  
  1807. Remember when declaring the PATTERN_LOOP variable to initialize it as 0.
  1808. Jumping back should just be a matter of setting your row number to the stored
  1809. pattern loop number, and once the row is finished it should start playing at
  1810. the specified position again.
  1811. This is how my function works, in the UPDATE_NOTE function, or handler for
  1812. tick 0.
  1813. case 0x6 : if (eparmy == 0) patlooprow = row;   // store position of param=0
  1814.        else {
  1815.         if (patloopno == 0) patloopno=eparmy;   // set times if 0
  1816.         else patloopno--;                       // else subtract 1
  1817.         if (patloopno > 0) row = patlooprow-1;  // if looping do jump
  1818.        }
  1819.  
  1820. ┌────────────────────────────────────────────┐
  1821. │ ░▒▓ 5.23 Effect E7x (Tremolo WaveForm) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1822. └────────────────────────────────────────────┘
  1823. This effect set the waveform for the tremolo command to follow, just like
  1824. vibrato.
  1825.  
  1826. EG:
  1827. --- 00 E42 (I want to select the squarewave function for the tremolo command)
  1828. --- 00 E40 (I want to select the default sinewave for the tremolo command)
  1829.  
  1830. Range: x = tremolo function to select (0-7)
  1831.  
  1832. The following values of x select its corresponding tremolo function
  1833. x=0 : Set sine wave  (default)
  1834. x=1 : Set Ramp Down  |\|\|\     _   _
  1835. x=2 : Set Squarewave         |_| |_| |_
  1836. x=3 : Set Random     (anywhere)
  1837. x=4 : don't retrig Sine waveform
  1838. x=5 : don't retrig RampDown waveform
  1839. x=6 : don't retrig Squarewave waveform
  1840. x=7 : don't retrig random waveform
  1841.  
  1842. see section 5.20 for information.
  1843.  
  1844. ┌──────────────────────────────────────────┐
  1845. │ ░▒▓ 5.24 Effect E8x (16 pos panning) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1846. └──────────────────────────────────────────┘
  1847. This effect lets you do 16 position panning
  1848.  
  1849. EG:
  1850. --- 00 E80 (I want to set the channel's pan value to the far left)
  1851. --- 00 E8F (I want to set the channel's pan value to the far right)
  1852.  
  1853. Range: x=position to pan too (0h-0Fh)
  1854.  
  1855. On tick 0, just read in the parameter and set the relative panning value for
  1856. the channel.
  1857.  
  1858. ┌───────────────────────────────────────┐
  1859. │ ░▒▓ 5.25 Effect E9x (Retrig Note) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]
  1860. └───────────────────────────────────────┘
  1861. This effect retiggers the current note every x ticks.
  1862.  
  1863. EG:
  1864. C-2 01 E93 (I want to retrig the note every 3 ticks - at speed 6 this would
  1865. --- 00 000                                            retrig it only once)
  1866. C-2 01 E91 (I want to retrig the note every tick - at speed 6 this would
  1867.                            retrig the note 5 times)
  1868. Range: x=ticks between retriggers (0h-0Fh)
  1869.  
  1870. On this effect you need to use the modulus operator to check when the retrig
  1871. should happen.  If x is 1 say, then it should retrig the note SPEED number of
  1872. times in one note.
  1873. ie.  
  1874.   tick MOD 1 = 0 always, so you would be retrigging every note.
  1875.   tick MOD 2 = 0 on even numbers, 1 on odd numbers, so you would be retrigging
  1876.          every other note.
  1877. etc.
  1878. When it does happen just play out the note as you would normally.  The note is
  1879. played on tick 0 as it would normally be.
  1880.  
  1881. ┌────────────────────────────────────────────┐
  1882. │ ░▒▓ 5.26 Effect EAx (Fine VolSlide Up) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1883. └────────────────────────────────────────────┘
  1884. This effect slides the volume up x values per row.
  1885.  
  1886. EG:
  1887. C-2 01 C00 (I want to start at note at volume 0)
  1888. --- 00 EA1 (Now I want to slide the volume up for the channel by 1 unit)
  1889. --- 00 EA1 (keep sliding up by 1 unit...)
  1890.  
  1891. Range: x= amount to slide up by. (0h-Fh)
  1892.  
  1893. This effect is only processed once per row, on tick 0, and it is as simple
  1894. as just adding x to the current channel's volume. 
  1895. It is only processed on tick 0, and is not touched at all in the other ticks.
  1896. The only checking to be done is for volumes larger than 64.
  1897. hint: for all these volume commands, only do the checking for bounds once,
  1898. just before you actually set the volume.
  1899.  
  1900. ┌──────────────────────────────────────────────┐
  1901. │ ░▒▓ 5.27 Effect EBx (Fine VolSlide Down) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1902. └──────────────────────────────────────────────┘
  1903. This effect slides the volume up x values per row.
  1904.  
  1905. EG:
  1906. C-2 01 EB1 (I want to slide the volume down for the channel by 1 unit)
  1907. --- 00 EB1 (keep sliding down by 1 unit...)
  1908. --- 00 EB1 (keep sliding down by 1 unit...)
  1909.  
  1910. Range: x= amount to slide up by. (0h-Fh)
  1911.  
  1912. This effect is only processed once per row, on tick 0, and it is as simple
  1913. as just subtracting x from the current channel's volume. 
  1914. It is only processed on tick 0, and is not touched at all in the other ticks.
  1915. The only checking to be done is for volumes smaller than 0.
  1916. hint: for all these volume commands, only do the checking for bounds once,
  1917. just before you actually set the volume.
  1918.  
  1919. ┌────────────────────────────────────┐
  1920. │ ░▒▓ 5.28 Effect ECx (Cut Note) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]
  1921. └────────────────────────────────────┘
  1922. This effect cuts the volume of the note to 0 after x amount of ticks.
  1923.  
  1924. EG: (at speed 6 say)
  1925. C-2 01 EC3 (I want to stop the note at tick 3, or half way between 2 notes)
  1926.  
  1927. Range: x= number of ticks to wait before zeroing samples volume. (0h-Fh)
  1928.  
  1929. This effect is ignored on tick 0, but on tick x when you are updating tick
  1930. based effects, then just set the volume of the channel to 0.
  1931. Of course if the user specified x as a number more than the speed of the song,
  1932. then it would be ok because it would never get to tick x, and the effect is
  1933. ignored.
  1934.  
  1935. ┌──────────────────────────────────────┐
  1936. │ ░▒▓ 5.29 Effect EDx (Delay Note) ▓▒░ │ UPDATED: T0 [N] : INBETWEEN [Y]
  1937. └──────────────────────────────────────┘
  1938. This effect waits for x amount of ticks before it actually plays the sample.
  1939.  
  1940. EG: (at speed 6 say)
  1941. C-2 01 ED4 (I want to delay playing this note for another 4 ticks)
  1942.  
  1943. Range: x= number of ticks to wait before playing sample. (0h-Fh)
  1944.  
  1945. This effect is ignored on tick 0, AND you must make sure you don't play the
  1946. sample on tick 0.
  1947. When you arrive at tick x then just play the sample as you would normally.
  1948. Again if the user specified x as a number more than the speed of the song,
  1949. then it would be ok because it would never get to tick x, and the effect is
  1950. ignored.
  1951.  
  1952. ┌─────────────────────────────────────────┐
  1953. │ ░▒▓ 5.30 Effect EEx (Pattern Delay) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1954. └─────────────────────────────────────────┘
  1955. This effect delays the pattern for the time it would take to play x number of
  1956. notes.
  1957.  
  1958. EG:
  1959. C-2 01 EE8 (I want to play the c-2 note then wait for 8 notes before..
  1960. C-2 01 000  ... playing the next note)
  1961.  
  1962. Range: x= number of notes to delay pattern for. (0h-Fh)
  1963.  
  1964. To implement this effect you are going to have to modify your main interrupt
  1965. handler (see section 3.3): 
  1966.  
  1967. You are going to have to keep a counter that is subtracted every time your
  1968. SPEED number of ticks is up, but don't play the note.  You must still keep
  1969. playing the effects though.
  1970.  
  1971. It would look something like this.
  1972. if (tick >= speed) {
  1973.     ... blah blah blah etc...
  1974.     if (patdelay == 0) {
  1975.         increment row.
  1976.         playnote.
  1977.     }
  1978.     else patdelay --;
  1979. }
  1980. else doeffects
  1981.  
  1982. This just boils down to not playing the note or incrementing the row for x
  1983. number of notes, until the pattern delay counter is 0.  When it is 0 the mod
  1984. should keep playing as if nothing had happened.
  1985.  
  1986. ┌───────────────────────────────────────┐
  1987. │ ░▒▓ 5.31 Effect EFx (Invert Loop) ▓▒░ │ UPDATED: T0 [Y] : INBETWEEN [N]
  1988. └───────────────────────────────────────┘
  1989. This effect inverts a sample loop or plays it backwards.
  1990.  
  1991. EG:
  1992. C-2 01 EF4 (I want to play the loop in this sample backwards at speed 4)
  1993.  
  1994. Range: x = speed to set invert loop at (0h-0Fh)
  1995.  
  1996. This effect is not supported in any player or tracker.  Don't bother with it.
  1997.  
  1998.  
  1999. ┌────────────────────────────────────────────────────────────────────────────┐
  2000. │                   ░▒▓          : SECTION 6 :          ▓▒░                  │
  2001. │                   ░▒▓ Protracker 1.1B Format Document ▓▒░                  │
  2002. └────────────────────────────────────────────────────────────────────────────┘
  2003.  
  2004. Offset  Bytes  Description
  2005.    0     20    Songname. Remember to put trailing null bytes at the end...
  2006.  
  2007. Information for sample 1-31:
  2008.  
  2009. Offset  Bytes  Description
  2010.   20     22    Samplename for sample 1. Pad with null bytes.
  2011.   42      2    Samplelength for sample 1. Stored as number of words.
  2012.            Multiply by two to get real sample length in bytes.
  2013.   44      1    Lower four bits are the finetune value, stored as a signed
  2014.            four bit number. The upper four bits are not used, and
  2015.            should be set to zero.
  2016.            Value:  Finetune:
  2017.          0        0
  2018.          1       +1
  2019.          2       +2
  2020.          3       +3
  2021.          4       +4
  2022.          5       +5
  2023.          6       +6
  2024.          7       +7
  2025.          8       -8
  2026.          9       -7
  2027.          A       -6
  2028.          B       -5
  2029.          C       -4
  2030.          D       -3
  2031.          E       -2
  2032.          F       -1
  2033.  
  2034.   45      1    Volume for sample 1. Range is $00-$40, or 0-64 decimal.
  2035.   46      2    Repeat point for sample 1. Stored as number of words offset
  2036.            from start of sample. Multiply by two to get offset in bytes.
  2037.   48      2    Repeat Length for sample 1. Stored as number of words in
  2038.            loop. Multiply by two to get replen in bytes.
  2039.  
  2040. Information for the next 30 samples starts here.  It's just like the info for
  2041. sample 1.
  2042.  
  2043. Offset  Bytes  Description
  2044.   50     30    Sample 2...
  2045.   80     30    Sample 3...
  2046.    .
  2047.    .
  2048.    .
  2049.  890     30    Sample 30...
  2050.  920     30    Sample 31...
  2051.  
  2052. Offset  Bytes  Description
  2053.  950      1    Songlength. Range is 1-128.
  2054.  951      1    Well... this little byte here is set to 127, so that old
  2055.            trackers will search through all patterns when loading.
  2056.            Noisetracker uses this byte for restart, but we don't.
  2057.  952    128    Song positions 0-127. Each hold a number from 0-63 that
  2058.            tells the tracker what pattern to play at that position.
  2059. 1080      4    The four letters "M.K." - This is something Mahoney & Kaktus
  2060.            inserted when they increased the number of samples from
  2061.            15 to 31. If it's not there, the module/song uses 15 samples
  2062.            or the text has been removed to make the module harder to
  2063.            rip. Startrekker puts "FLT4" or "FLT8" there instead.
  2064.  
  2065. Offset  Bytes  Description
  2066. 1084    1024   Data for pattern 00.
  2067.    .
  2068.    .
  2069.    .
  2070. xxxx  Number of patterns stored is equal to the highest patternnumber
  2071.       in the song position table (at offset 952-1079).
  2072.  
  2073. Each note is stored as 4 bytes, and all four notes at each position in
  2074. the pattern are stored after each other.
  2075.  
  2076. 00 -  chan1  chan2  chan3  chan4
  2077. 01 -  chan1  chan2  chan3  chan4
  2078. 02 -  chan1  chan2  chan3  chan4
  2079. etc.
  2080.  
  2081. Info for each note:
  2082.  
  2083.  _____byte 1_____   byte2_    _____byte 3_____   byte4_
  2084. /                 /        /                 /
  2085. 0000          0000-00000000  0000          0000-00000000
  2086.  
  2087. Upper four    12 bits for    Lower four    Effect command.
  2088. bits of sam-  note period.   bits of sam-
  2089. ple number.                  ple number.
  2090.  
  2091. Periodtable for Tuning 0, Normal
  2092.   C-1 to B-1 : 856,808,762,720,678,640,604,570,538,508,480,453
  2093.   C-2 to B-2 : 428,404,381,360,339,320,302,285,269,254,240,226
  2094.   C-3 to B-3 : 214,202,190,180,170,160,151,143,135,127,120,113
  2095.  
  2096. To determine what note to show, scan through the table until you find
  2097. the same period as the one stored in byte 1-2. Use the index to look
  2098. up in a notenames table.
  2099.  
  2100.