home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog-asm / examples.lzh / EXAMPLES / SAMP / SAMP.DOC < prev    next >
Encoding:
Text File  |  1991-08-16  |  52.7 KB  |  1,123 lines

  1.                        IFF FORM "SAMP" Sampled Sound
  2.  
  3.  Date:   June 17,1988
  4.  From:   Jim Fiore and Jeff Glatt, dissidents
  5.  Status: Adopted by our company in lieu of any "official" alternative
  6.  
  7.    The form "SAMP" is a file format used to store sampled sound data in some
  8. ways like the current standard, "8SVX". Unlike "8SVX", this new format is not
  9. restricted to 8 bit sample data. There can be more than one waveform per
  10. octave, and the lengths of different waveforms do not have to be factors of
  11. 2. In fact, the lengths (waveform size) and playback mapping (which musical
  12. notes each waveform will "play") are independently determined for each wave-
  13. form. Furthermore, this format takes into account the MIDI sample dump stan-
  14. dard (the defacto standard for musical sample storage), while also incorpo-
  15. rating the ability to store Amiga specific info (for example, the sample data
  16. that might be sent to an audio channel which is modulating another channel).
  17. Although this form can be used to store "sound effects" (typically oneShot
  18. sounds played at a set pitch), it is primarily intended to correct the many
  19. deficiencies of the "8SVX" form in regards to musical sampling. Because the
  20. emphasis is on musical sampling, this format relies on the MIDI (Musical
  21. Instrument Digital Interface) method of describing "sound events" as does
  22. virtually all currently manufactured, musical samplers. In addition, it at-
  23. tempts to incorporate features found on many professional music samplers, in
  24. anticipation that future Amiga models will implement 16 bit sampling, and
  25. thus be able to achieve this level of performance. Because this format is 
  26. more complex than "8SVX", programming examples to demonstrate the use of this
  27. format have been included in both C and assembly. Also, a library of func-
  28. tions to read and write SAMP files is available, as well as an assembly
  29. language library which has functions to "play" SAMP files.
  30.  
  31.   SEMANTICS: When MIDI literature talks about a sample, usually it means a
  32. collection of many sample points that make up what we call a "wave".
  33.  
  34.         =====SIMILARITIES AND DIFFERENCES FROM THE "8SVX" FORM=======
  35.  
  36.    Like "8SVX", this new format uses headers to separate the various sections
  37. of the sound file into chunks. Some of the chunks are exactly the same since
  38. there wasn't a need to improve them. The chunks that remain unchanged are as
  39. follows:
  40.  
  41.    "(c) "
  42.    "AUTH"
  43.    "ANNO"
  44.  
  45.   Since these properties are all described in the original "8SVX" document,
  46. please refer to that for a description of these chunks and their uses. Like
  47. the "8SVX" form, none of these chunks are required to be in a sound file.
  48. When they do appear, they must be padded out to an even number of bytes.
  49.  
  50.   Furthermore, two "8SVX" chunks no longer exist as they have been incorpo-
  51. rated into the "BODY" chunk. They are:
  52.  
  53.    "ATAK"
  54.    "RLSE"
  55.  
  56.   Since each wave can be completely different than the other waves in the 
  57. sound file (one wave might be middle C on a piano, and another might be a
  58. snare drum hit), it is necessary for each wave to have its own envelope de-
  59. scription, and name.
  60.  
  61.   The major changes from the "8SVX" format are in the "MHDR", "NAME", and
  62. "BODY" chunks.
  63.  
  64.           =================THE "SAMP" HEADER================
  65.  
  66.  At the very beginning of a sound file is the "SAMP" header. This is used to
  67. determine if the disk file is indeed a SAMP sound file. It's attributes are
  68. as follows:
  69.  
  70.    #define ID_SAMP MakeID('S','A','M','P')
  71.  
  72.   In assembly, this looks like:
  73.  
  74.       CNOP 0,2  ;word-align
  75.  
  76. SAMP         dc.b  'SAMP'
  77. sizeOfChunks dc.l  [sizes of subsequent chunks summed]
  78.  
  79.              =================THE "MHDR" CHUNK=================
  80.  
  81.   The required "MHDR" chunk immediately follows the "SAMP" header and consists
  82. of the following components:
  83.  
  84.   #define ID_MHDR MakeID('M','H','D','R')
  85.  
  86.   /* MHDR size is always 516 BYTES (Does not include this 8 byte header). */
  87.  
  88.   typedef struct{
  89.      UBYTE playMap[128][4],  /* a map of which 4 wave numbers to use for
  90.                                  each Midi Note, 0 to 127 respectively */
  91.      numOfWaves,              /* The number of waves in this file */
  92.      sampleFormat,            /* # of ORIGINAL significant bits from 8-28 */
  93.      Flags,                   /* Various bits indicate various functions */
  94.      playMode;                /* determines play MODE of the playMap */
  95.    } MIDIVoiceHeader;
  96.  
  97. The playMap is an array of 512 bytes. The Midi Spec 1.0 designates that there
  98. are 128 possible note numbers (pitches), 0 to 127. There are 4 bytes in
  99. playMap for EACH of the 128 Midi Note numbers. For example, the first 4 bytes
  100. in playMap pertain to Midi Note #0. Of the 4 bytes, the first byte is the
  101. wave number to play back on Amiga audio channel 0. The second byte is the
  102. wave number to play back on Amiga audio channel 1, etc. In this way, a single
  103. Midi Note Number could simultaneously trigger a sound event on each of the 4
  104. Amiga audio channels. There can be a total of 255 waves in a "SAMP" file.
  105. They are numbered from 1 to 255. A wave number of 0 is reserved to indicate
  106. that NO WAVE number should be played back. All four of the playMap bytes
  107. could even be the same wave number. This would cause the wave to be output of
  108. all 4 Amiga channels simultaneously. Consider the following example:
  109.  
  110.   The first 4 bytes of playMap are  1,3,0,200.
  111.  
  112.   If a sample playing program receives (from the serial port or another task
  113. perhaps) Midi Note Number 0, the following should occur:
  114.  
  115.   1) The sampler plays back wave 1 on Amiga audio channel
  116.      number 0 (because the first playMap byte is 1).
  117.   2) The sampler plays back wave 3 on Amiga audio channel
  118.      number 1 (because the second playMap byte is 3).
  119.   3) The sampler does not effect Amiga audio channel 2 in
  120.      any way (because the third playMap byte is a 0).
  121.   4) The sampler plays back wave 200 on Amiga audio channel
  122.      number 4 (because the fourth playMap byte is 200).
  123.  
  124.  (This assumes INDEPENDANT CHANNEL play MODE to be discussed later in this
  125.   article.)
  126.  
  127.   In effect, the purpose of the playMap array is to determine which (if any)
  128. waves are to be played back on the 4 Amiga audio channels for each of the 128
  129. possible Midi Note Numbers.
  130.  
  131.   numOfWaves is simply the number of waves in the sound file.
  132.  
  133.   sampleFormat is the number of significant bits in every sample of a wave.
  134. For example, if sampleFormat = 8, then this means that the sample data is an
  135. 8 bit format, and that every sample of the wave can be expressed by a single
  136. BYTE. (A 16 bit sample would need a WORD for every sample point).
  137.  
  138.   Each bit of the Flags byte, when set, means the following:
  139.  
  140. Bit #0 - File continued on another disc. This might occur if the SAMP file
  141.          was too large to fit on 1 floppy. The accepted practice (as incor-
  142.          porated by Yamaha's TX sampler and Casio's FZ-1 for example) is to
  143.          dump as much as possible onto one disc and set a flag to indicate
  144.          that more is on another disc's file. The name of the files must
  145.          be the same. The continuation file should have its own SAMP header
  146.          MHDR, and BODY chunks. This file could even have its continuation
  147.          bit set, etc. Never chop a sample wave in half. Always close the
  148.          file on 1 disc after the last wave which can be completely saved.
  149.          Resume with the next wave within the BODY of the continuation file.
  150.          Also, the numOfWaves in each file's BODY should be the number saved
  151.          on that disc (not the total number in all combined disk files).
  152.     See the end of this document for filename conventions.
  153.  
  154.  In C, a received Midi Note should be interpreted as follows:
  155.  
  156.   MapOffset = (UBYTE) MidiNoteNumber * 4;  /* MidiNoteNumber is the received note */
  157.   chan0waveNum = (UBYTE) playMap[MapOffset];
  158.   chan1waveNum = (UBYTE) playMap[MapOffset+1];
  159.   chan2waveNum = (UBYTE) playMap[MapOffset+2];
  160.   chan3waveNum = (UBYTE) playMap[MapOffset+3];
  161.  
  162.   if (chan0waveNum != 0)
  163.   { /* get the pointer to wave #1's data, determine the values
  164.        that need to be passed to the audio device, and play this
  165.        wave on Amiga audio channel #0 (if INDEPENDANT playMode) */
  166.   }
  167.  
  168.    /* do the same with the other 3 channel's wave numbers */
  169.  
  170.   In assembly, the "MHDR" structure looks like this:
  171.  
  172.              CNOP 0,2
  173. MHDR         dc.b 'MHDR'
  174. sizeOfMHDR   dc.l 516    ;always 516 bytes to follow
  175. playMap      dc.b [128 x 4 bytes of initialized values]
  176. numOfWaves   dc.b [a byte count of the # of waves in the file]
  177. sampleFormat dc.b [a byte count of the # of ORIGINAL significant bits]
  178. Flags        dc.b [bit mask]
  179. playMode     dc.b [play MODE discussed later]
  180.  
  181.  
  182.    and a received MidiNoteNumber is interpreted as follows:
  183.  
  184.    moveq   #0,d0
  185.    move.b  MidiNoteNumber,d0  ;this is the received midi note #
  186.    bmi.s   Illegal_Number     ;exit, as this is an illegal midi note #
  187.    add.b   d0,d0
  188.    add.w   d0,d0              ;MidiNoteNumber x 4
  189.    lea     playMap,a0
  190.    adda.l  d0,a0
  191.    move.b  (a0)+,chan0waveNum
  192.    move.b  (a0)+,chan1waveNum
  193.    move.b  (a0)+,chan2waveNum
  194.    move.b  (a0),chan3waveNum
  195.  
  196.       tst.b   chan0waveNum
  197.       beq.s   Chan1
  198.  ;Now get the address of this wave number's sample data, determine the
  199.  ;values that need to be passed to the audio device, and output the wave's
  200.  ;data on Amiga chan 0 (assuming INDEPENDANT playMode).
  201.  
  202. Chan1 tst.b chan1waveNum
  203.       beq.s Chan2
  204.  ;do the same for the other wave numbers, etc.
  205.  
  206.     =====================THE "NAME" CHUNK=========================
  207.  
  208.   #define ID_NAME MakeID('N','A','M','E')
  209.  
  210.   If a NAME chunk is included in the file, then EVERY wave must have a name.
  211. Each name is NULL-terminated. The first name is for the first wave, and it
  212. is immediately followed by the second wave's name, etc. It is legal for a
  213. wave's name to be simply a NULL byte. For example, if a file contained 4
  214. waves and a name chunk, the chunk might look like this:
  215.  
  216.            CNOP 0,2
  217.  
  218. Name       dc.b 'NAME'
  219. sizeOfName dc.l 30
  220.       dc.b 'Snare Drum',0  ;wave 1
  221.       dc.b 'Piano 1',0     ;wave 2
  222.       dc.b 'Piano A4',0    ;wave 3
  223.            dc.b 0          ;wave 4
  224.            dc.b 0
  225.  
  226.   NAME chunks should ALWAYS be padded out to an even number of bytes. (Hence
  227. the extra NULL byte in this example). The chunk's size should ALWAYS be even
  228. consequently. DO NOT USE the typical IFF method of padding a chunk out to an
  229. even number of bytes, but allowing an odd number size in the header.
  230.  
  231.             ==============THE "BODY" CHUNK===============
  232.  
  233.  The "BODY" chunk is CONSIDERABLY different than the "8SVX" form. The
  234. structure is as follows:
  235.  
  236.    #define ID_BODY MakeID('B','O','D','Y')
  237.  
  238.  
  239.    /* Now for the first waveHeader. Each wave has an 80 byte waveHeader
  240.       followed by data. */
  241.  typedef struct {
  242.    ULONG  waveSize;        /* total # of BYTES in the wave (MUST be even) */
  243.    UWORD  midiSampNum;     /* ONLY USED for Midi Dumps */
  244.    UBYTE  loopType,        /* ONLY USED for Midi Dumps */
  245.    InstrumentType;         /* Used for searching for a certain instrument */
  246.    ULONG  samplePeriod,    /* in nanoseconds at original pitch */
  247.    sampleRate,             /* # of samples per second at original pitch */
  248.    loopStartPoint,         /* an offset in BYTES (from the beginning of the
  249.                               of the wave) where the looping portion of the
  250.                               wave begins. Set to waveSize if no loop. */
  251.    loopEndPoint;           /* an offset in BYTES (from the beginning of the
  252.                               of the wave) where the looping portion of the
  253.                               wave ends. Set to waveSize if no loop. */
  254.    UBYTE  rootNote,        /* the Midi Note # that plays back original pitch */
  255.    velocityStart;            /* 0 = NO velocity effect, 128 =
  256.                                 negative direction, 64 = positive
  257.                                 direction (it must be one of these 3) */
  258.    UWORD velStartTable[16];  /* contains 16 successive offset values
  259.                                 in BYTES from the beginning of the wave */
  260.  
  261.   /* The ATAK and RLSE segments contain an EGPoint[] piece-wise
  262.      linear envelope just like 8SVX. The structure of an EGPoint[]
  263.      is the same as 8SVX. See that document for details. */
  264.  
  265.    ULONG  sizeOfATAK,     /* # of BYTES in subsequent ATAK envelope.
  266.                              If 0, then no ATAK data for this wave. */
  267.    sizeOfRLSE,            /* # of BYTES in subsequent RLSE envelope
  268.                              If 0, then no RLSE envelope follows */
  269.  
  270.   /* The FATK and FRLS segments contain an EGPoint[] piece-wise
  271.      linear envelope for filtering purposes. This is included in
  272.      the hope that future Amiga audio will incorporate a VCF
  273.      (Voltage Controlled Filter). Until then, if you are doing any
  274.      non-realtime digital filtering, you could store info here. */
  275.  
  276.   sizeOfFATK,            /* # of BYTES in FATK segment */
  277.   sizeOfFRLS,            /* # of BYTES in FRLS segment */
  278.  
  279.   sizeOfUserData;        /*   # of BYTES in the following data
  280.                               segment (not including typeOfData).
  281.                               If zero, then no user data */
  282.   UWORD  typeOfData;     /* See explanation below. If sizeOfUserData
  283.                              = 0, then ignore this. */
  284.  
  285.  /* End of the waveInfo. Now the data. */
  286.  
  287.  /* The data for any ATAK, RLSE, FATK, FRLS, USER, and the actual wave
  288.     data for wave #1 follows */
  289.  
  290.  /* Now list each EGPoint[] for the VCA's (Voltage Controlled Amp)
  291.     attack portion */
  292.  /* Now list each EGPoint[] for the VCA's (Voltage Controlled Amp)
  293.     release portion */
  294.  /* include EGPoints[] if any for FATK */
  295.  /* include EGPoints[] if any for FRLS */
  296.  /* Now include the user data here if there is any. Just pad it out
  297.     to an even number of bytes and have sizeOfUserData reflect that. */
  298.  /* After the userdata (if any) is the actual sample data for
  299.    the wave (array). The size (in BYTES) of this segment is waveSize.
  300.    It MUST be padded out to an even number of bytes. */
  301.  
  302.  } WaveFormInfo;
  303.  
  304.  
  305.  /* END OF WAVE #1 */
  306.  
  307.  /* The structures for the other waves would now follow. They are
  308.     the same form as the first wave */
  309.  
  310. ;==================STRUCTURE OF AN INDIVIDUAL SAMPLE POINT==================
  311.  
  312.    Even though the next generation of computers will probably have 16 bit
  313. audio, and 8 bit sampling will quickly disappear, this spec has sizes expressed
  314. in BYTES. (ie loopStartPoint, waveSize, etc.) This is because each successive
  315. address in RAM is a byte to the 68000, and so calculating address offsets
  316. will be much easier with all sizes in BYTES. The Midi sample dump, on the 
  317. other hand, has sizes expressed in WORDS. What this means is that if you
  318. have a 16 bit sample, for example, the waveSize is the total number of BYTES,
  319. not WORDS, in the wave.
  320.   Also, there is no facility for storing a compression type. This is because
  321. sample data should be stored in linear format (as per the MIDI spec). Currently,
  322. all music samplers, regardless of their internal method of playing sample data
  323. must transmit and expect to receive sample dumps in a linear format. It is
  324. up to each device to translate the linear format into its own compression
  325. scheme. For example, if you are using an 8 bit compression scheme that yields
  326. a 14 bit linear range, you should convert each sample data BYTE to a decom-
  327. pressed linear WORD when you save a sound file. Set the MHDR's sampleFormat
  328. to 14. It is up to the application to do its own compression upon loading
  329. a file. The midi spec was set up this way because musical samplers need to
  330. pass sample data between each other, and computers (via a midi interface).
  331. Since there are almost as many data compression schemes on the market as
  332. there are musical products, it was decided that all samplers should expect
  333. data received over midi to be in LINEAR format. It seems logical to store it
  334. this way on disc as well. Therefore, any software program "need not know" how
  335. to decompress another software program's SAMP file. When 16 bit sampling is
  336. eventually implemented there won't be much need for compression on playback
  337. anyway. The continuation Flag solves the problem of disc storage as well.
  338.   Since the 68000 can only perform math on BYTES, WORDS, or LONGS, it has
  339. been decided that a sample point should be converted to one of these sizes
  340. when saved in SAMP as follows:
  341.  
  342.  ORIGINAL significant bits          SAMP sample point size
  343.  ­­­­­­­­­­­­­­­­­­­­­­­­­          ­­­­­­­­­­­­­­­­­­­­­­
  344.             8                               BYTE
  345.           9 to 16                           WORD
  346.           17 to 28                          LONG
  347.  
  348.   Furthermore, the significant bits should be left-justified since it is
  349. easier to perform math on the samples
  350.  
  351.   So, for example, an 8 bit sample point (like 8SVX) would be saved as a
  352. BYTE with all 8 bits being significant. The MHDR's sampleFormat = 8. No
  353. conversion is necessary.
  354.  
  355.   A 12 bit sample point should be stored as a WORD with the significant bits
  356. being numbers 2 to 15. (i.e shift the 12-bit WORD 2 places to the left). Bits
  357. 0 and 1 may be zero (unless some 16-bit math was performed and you wish to
  358. save these results). The MHDR's sampleFormat = 12. In this way, the sample
  359. may be loaded and manipulated as a 16-bit wave, but when transmitted via
  360. midi, it can be converted back to 12 bits (rounded and shifted right by 2).
  361.  
  362.   A 16 bit sample point would be saved as a WORD with all 16 bits being
  363. significant. The MHDR's sampleFormat = 16. No conversion is necessary.
  364.  
  365. --------------------------------------------------------------------
  366.  
  367.    The waveSize is, as stated, the number of BYTES in the wave's sample table.
  368. If your sample data consisted of the following 8 bit samples:
  369.  
  370.     BYTE  100,-90,80,-60,30,35,40,-30,-35,-40,00,12,12,10
  371.  
  372.  then waveSize = 14. (PAD THE DATA OUT TO AN EVEN NUMBER OF BYTES!)
  373.  
  374.   The midiSampNum is ONLY used to hold the sample number received from a MIDI
  375. Sample Dump. It has no bearing on where the wave should be placed in a SAMP
  376. file. Also, the wave numbers in the playMap are between 1 to 255, with 1 being
  377. the number of the first wave in the file. Remember that a wave number of 0 is
  378. reserved to mean "no wave to play back". Likewise, the loopType is only used
  379. to hold info from a MIDI sample dump.
  380.  
  381.    The InstrumentType is explained at the end of this document. Usually it
  382. should be set to 0.
  383.  
  384.    The rootNote is the Midi Note number that will play the wave back at it's
  385. original, recorded pitch. For example, consider the following excerpt of a
  386. playMap:
  387.  
  388.   playMap  {2,0,0,4       /* Midi Note #0 channel assignment */
  389.             4,100,1,0     /* Midi Note #1    "        "  */
  390.             1,4,0,0       /* Midi Note #2    "        "  */
  391.             60,2,1,1...}  /* Midi Note #3    "        "  */
  392.  
  393.   Notice that Midi Notes 0, 1, and 2 are all set to play wave number 4 (on
  394. Amiga channels 3, 0, and 1 respectively). If we set wave 4's rootNote = 1,
  395. then receiving Midi Note number 1 would play back wave 4 (on Amiga channel 0)
  396. at it's original pitch. If we receive a Midi Note number 0, then wave 4 would
  397. be played back on channel 3) a half step lower than it's original pitch. If we
  398. receive Midi Note number 2, then wave 4 would be played (on channel 1) a half
  399. step higher than it's original pitch. If we receive Midi Note number 3, then
  400. wave 4 would not be played at all because it isn't specified in the playMap
  401. bytes for Midi Note number 3.
  402.  
  403.   The sampleRate is the number of samples per second of the original pitch.
  404. For example, if sampleRate = 20000, then to play the wave at it's original
  405. pitch, the sampling period would be:
  406.  
  407.      (1/20000)/.279365 = .000178977
  408.  
  409. #define AUDIO_HARDWARE_FUDGE .279365
  410.  
  411. where .279365 is the Amiga Fudge Factor (a hardware limitation). Since the
  412. amiga needs to see the period in terms of microseconds, move the decimal place
  413. to the right 6 places and our sampling period = 179 (rounded to an integer).
  414. In order to play the wave at higher or lower pitches, one would need to
  415. "transpose" this period value. By specifying a higher period value, the Amiga
  416. will play back the samples slower, and a lower pitch will be achieved. By
  417. specifying a lower period value, the amiga will play back the sample faster,
  418. and a higher pitch will be achieved. By specifying this exact period, the wave
  419. will be played back exactly "as it was recorded (sampled)". ("This period is
  420. JUST RIGHT!", exclaimed GoldiLocks.) Later, a method of transposing pitch will
  421. be shown using a "look up" table of periods. This should prove to be the
  422. fastest way to transpose pitch, though there is nothing in the SAMP format
  423. that compels you to do it this way.
  424.  
  425.   The loopStartPoint is a BYTE offset from the beginning of the wave to where
  426. the looping portion of the wave begins. For example, if SampleData points to
  427. the start of the wave, then SampleData + loopStartPoint is the start address
  428. of the looping portion. In 8SVX, the looping portion was referred to as
  429. repeatHiSamples. The data from the start of the wave up to the start of the
  430. looping portion is the oneShot portion of the wave. loopEndPoint is a BYTE
  431. offset from the beginning of the wave to where the looping portion ends. This
  432. might be the very end of the wave in memory, or perhaps there might be still
  433. more data after this point. You can choose to ignore this "trailing" data and
  434. play back the two other portions of the wave just like an 8SVX file (except
  435. that there are no other interpolated octaves of this wave).
  436.  
  437.   velStartTable contains 16 BYTE offsets from the beginning of the wave. Each
  438. successive value should be greater (or equal to) the preceding value. If
  439. velocityStart = POSITIVE (64), then for each 8 increments in Midi Velocity
  440. above 0, you move UP in the table, add this offset to the wave's beginning
  441. address (start of oneShot), and start playback at that address. Here is a 
  442. table relating received midi note-on velocity vs. start playback address for
  443. POSITIVE velocityStart. SamplePtr points to the beginning of the sample.
  444.  
  445.  If midi velocity = 0, then don't play a sample, this is a note off
  446.  If midi velocity = 1 to 7, then start play at SamplePtr + velStartTable[0]
  447.  If midi velocity = 8 to 15, then start at SamplePtr + velStartTable[1]
  448.  If midi velocity = 16 to 23, then start at SamplePtr + velStartTable[2]
  449.  If midi velocity = 24 to 31, then start at SamplePtr + velStartTable[3]
  450.  If midi velocity = 32 to 39, then start at SamplePtr + velStartTable[4]
  451.  If midi velocity = 40 to 47, then start at SamplePtr + velStartTable[5]
  452.  If midi velocity = 48 to 55, then start at SamplePtr + velStartTable[6]
  453.  If midi velocity = 56 to 63, then start at SamplePtr + velStartTable[7]
  454.  If midi velocity = 64 to 71, then start at SamplePtr + velStartTable[8]
  455.  If midi velocity = 72 to 79, then start at SamplePtr + velStartTable[9]
  456.  If midi velocity = 80 to 87, then start at SamplePtr + velStartTable[10]
  457.  If midi velocity = 88 to 95, then start at SamplePtr + velStartTable[11]
  458.  If midi velocity = 96 to 103, then start at SamplePtr + velStartTable[12]
  459.  If midi velocity = 104 to 111, then start at SamplePtr + velStartTable[13]
  460.  If midi velocity = 112 to 119, then start at SamplePtr + velStartTable[14]
  461.  If midi velocity = 120 to 127, then start at SamplePtr + velStartTable[15]
  462.  
  463. We don't want to specify a scale factor and use integer division to find the
  464. sample start. This would not only be slow, but also, it could never be certain
  465. that the resulting sample would be a zero crossing if the start point is calcu-
  466. lated "on the fly". The reason for having a table is so that the offsets can be
  467. be initially set on zero crossings via an editor. This way, no audio "clicks"
  468. guaranteed. This table should provide enough resolution.
  469.  
  470.    If velocityStart = NEGATIVE (128), then for each 8 increments in midi
  471. velocity, you start from the END of velStartTable, and work backwards. Here
  472. is a table for NEGATIVE velocity start.
  473.  
  474.  If midi velocity = 0, then don't play a sample, this is a note off
  475.  If midi velocity = 1 to 7, then start play at SamplePtr + velStartTable[15]
  476.  If midi velocity = 8 to 15, then start at SamplePtr + velStartTable[14]
  477.  If midi velocity = 16 to 23, then start at SamplePtr + velStartTable[13]
  478.  If midi velocity = 24 to 31, then start at SamplePtr + velStartTable[12]
  479.  If midi velocity = 32 to 39, then start at SamplePtr + velStartTable[11]
  480.  If midi velocity = 40 to 47, then start at SamplePtr + velStartTable[10]
  481.  If midi velocity = 48 to 55, then start at SamplePtr + velStartTable[9]
  482.  If midi velocity = 56 to 63, then start at SamplePtr + velStartTable[8]
  483.  If midi velocity = 64 to 71, then start at SamplePtr + velStartTable[7]
  484.  If midi velocity = 72 to 81, then start at SamplePtr + velStartTable[6]
  485.  If midi velocity = 80 to 87, then start at SamplePtr + velStartTable[5]
  486.  If midi velocity = 88 to 95, then start at SamplePtr + velStartTable[4]
  487.  If midi velocity = 96 to 103, then start at SamplePtr + velStartTable[3]
  488.  If midi velocity = 104 to 111, then start at SamplePtr + velStartTable[2]
  489.  If midi velocity = 112 to 119, then start at SamplePtr + velStartTable[1]
  490.  If midi velocity = 120 to 127, then start at SamplePtr + velStartTable[0]
  491.  
  492.  In essence, increasing midi velocity starts playback "farther into" the wave
  493. for POSITIVE velocityStart. Increasing midi velocity "brings the start point
  494. back" toward the beginning of the wave for NEGATIVE velocityStart.
  495.  
  496.  If velocityStart is set to NONE (0), then the wave's playback start should
  497. not be affected by the table of offsets.
  498.  
  499.  What is the use of this feature? As an example, when a snare drum is hit with
  500. a soft volume, its initial attack is less pronounced than when it is struck
  501. hard. You might record a snare being hit hard. By setting velocityStart to a
  502. NEGATIVE value and setting up the offsets in the Table, a lower midi velocity
  503. will "skip" the beginning samples and thereby tend to soften the initial
  504. attack. In this way, one wave yields a true representation of its instrument
  505. throughout its volume range. Furthermore, stringed and plucked instruments
  506. (violins, guitars, pianos, etc) exhibit different attacks at different
  507. volumes. velocityStart makes these kinds of waves more realistic via a software
  508. implementation. Also, an application program can allow the user to enable/
  509. disable this feature. See the section "Making the Velocity Table" for info on
  510. how to best choose the 16 table values.
  511.  
  512.         =========MIDI VELOCITY vs. AMIGA CHANNEL VOLUME============
  513.  
  514.  The legal range for Midi Velocity bytes is 0 to 127. (A midi velocity of 0
  515.  should ALWAYS be interpreted as a note off).
  516.  
  517.  The legal range for Amiga channel volume is 0 to 64. Since this is half of
  518.  the midi range, a received midi velocity should be divided by 2 and add 1
  519.  (but only AFTER checking for a received midi velocity of 0).
  520.  
  521.   An example of how to implement a received midi velocity in C:
  522.  
  523.   If ( ReceivedVelocity != 0 && ReceivedVelocity < 128 )
  524.   {   /* the velocity byte of a midi message */
  525.       If (velocityStart != 0)
  526.       {
  527.           tableEntry = ReceivedVelocity / 8;
  528.           If (velocityStart == 64)
  529.           {    /* Is it POSITIVE */
  530.                startOfWave = SamplePtr + velStartTable[tableEntry];
  531.                            /* ^where to find the sample start point */
  532.           }
  533.           If (velocityStart == 128)
  534.           {    /* Is it NEGATIVE */
  535.                startOfWave = SamplePtr + velStartTable[15 - tableEntry];
  536.           }
  537.           volume = (receivedVelocity/2 + 1;  /* playback volume */
  538.           /* Now playback the wave */
  539.       }
  540.   }
  541.  
  542.   In assembly,  the BODY chunk and previous example are:
  543.  
  544.            CNOP 0,2
  545. BodyHEADER dc.b 'BODY'
  546. sizeOfBody dc.l  [total bytes in the BODY chunk not counting 8 byte header]
  547.  
  548.    ; Now for the first wave
  549. waveSize       dc.l  ;[total # of BYTES in this wave (MUST be even)]
  550. midiSampNum    dc.w  ;[from Midi Sample Dump]  ; ONLY USED for Midi Dumps
  551. loopType       dc.b  ;[0 or 1]                 ; ONLY USED for Midi Dumps
  552. InstrumentType dc.b  0
  553. samplePeriod   dc.l    ;[period in nanoseconds at original pitch]
  554. sampleRate     dc.l    ;[# of samples per second at original pitch]
  555. loopStartPoint dc.l    ;[an offset in BYTES (from the beginning of the
  556.                        ; of the wave) to where the looping
  557.                        ; portion of the wave begins.]
  558. loopEndPoint   dc.l    ;[an offset in BYTES (from the beginning of the
  559.                        ; of the wave) to where the looping
  560.                        ; portion of the wave ends]
  561. rootNote       dc.b    ;[the Midi Note # that plays back original pitch]
  562. velocityStart  dc.b    ;[0, 64, or 128]
  563. velStartTable  dc.w    ;[first velocity offset]
  564.                dc.w    ;[second velocity offset]...etc
  565.                ds.w 14 ;...for a TOTAL of 16 velocity offsets
  566.  
  567. sizeOfATAK  dc.l  ;# of BYTES in subsequent ATAK envelope.
  568.                   ;If 0, then no ATAK data for this wave.
  569. sizeOfRLSE  dc.l  ;# of BYTES in subsequent RLSE envelope
  570.                   ;If 0, then no RLSE data
  571. sizeOfFATK  dc.l  ;# of BYTES in FATK segment
  572. sizeOfFRLS  dc.l  ;# of BYTES in FRLS segment
  573. sizeOfUserData dc.l  ;# of BYTES in the following data
  574.                      ;segment (not including typeOfData).
  575.                      ;If zero, then no user data
  576. typeOfData  dc.w  ; See explanation below. If sizeOfUserData
  577.                   ; = 0, then ignore this.
  578.  
  579.   ;Now include the EGpoints[] (data) for the ATAK if any
  580.   ;Now the EGpoints for the RLSE
  581.   ;Now the EGpoints for the FATK
  582.   ;Now the EGpoints for the FLSR
  583.   ;Now include the user data here if there is any. Just pad
  584.   ;it out to an even number of bytes.
  585.   ;After the userdata (if any) is the actual sample data for
  586.   ;the wave. The size (in BYTES) of this segment is waveSize.
  587.   ;It MUST be padded out to an even number of bytes.
  588.  
  589.   ; END OF WAVE #1
  590.  
  591.   lea      SampleData,a0        ;the start addr of the sample data
  592.   moveq    #0,d0
  593.   move.b   ReceivedVelocity,d0  ;the velocity byte of a midi message
  594.   beq      A_NoteOff            ;If zero, branch to a routine to
  595.                                 ;process a note-off message.
  596.  
  597.   bmi      Illegal_Vol          ;exit if received velocity > 127
  598.   ;---Check for velocity start feature ON, and direction
  599.   move.b   velocityStart,d1
  600.   beq.s    Volume               ;skip the velocity offset routine if 0
  601.   bmi.s    NegativeVel          ;is it NEGATIVE? (128)
  602.  
  603.   ;---Positive velocity offset
  604.   move.l   d0,d1                ;duplicate velocity
  605.   lsr.b    #3,d1                ;divide by 8
  606.   add.b    d1,d1                ;x 2 because we need to fetch a word
  607.   lea      velStartTable,a1     ;start at table's HEAD
  608.   adda.l   d1,a1                ;go forward
  609.   move.w   (a1),d1              ;get the velocity offet
  610.   adda.l   d1,a0          ;where to start actual playback
  611.   bra.s    Volume
  612.  
  613.   ;---Negative velocity offset
  614.   move.l   d0,d1                ;duplicate velocity
  615.   lsr.b    #3,d1                ;divide by 8
  616.   add.b    d1,d1                ;x 2 because we need to fetch a word
  617.   lea      velStartTable+30,a1  ;start at table's END
  618.   suba.l   d1,a1                ;go backwards
  619.   move.w   (a1),d1              ;get the velocity offset
  620.   adda.l   d1,a0          ;where to start actual playback
  621.  
  622.   ;---Convert Midi velocity to an Amiga volume
  623. Volume  lsr.b    #1,d0          ;divide by 2
  624.         addq.b   #1,d0          ;an equivalent Amiga volume
  625.  
  626.  ;---Now a0 and d0 are the address of sample start, and volume
  627.  
  628. =================== AN EGpoint (envelope generator) ================
  629.  
  630.  A single EGpoint is a 6 byte structure as follows:
  631.  
  632. EGpoint1: dc.w ;[the duration in milliseconds]
  633.           dc.l ;[the volume factor - fixed point, 16 bits to the left of the
  634.                ;decimal point and 16 to the right.]
  635.  
  636.   The volume factor is a fixed point where 1.0 ($00010000) represents the
  637.   MAXIMUM volume possible. (i.e. No volume factor should exceed this value.)
  638.   The last EGpoint in the ATAK is always the sustain point. Each EG's volume
  639.   is determined from 0.0, not as a difference from the previous EG's volume.
  640.   I hope that this clears up the ambiguity in the original 8SVX document.
  641.   So, to recreate an amplifier envelope like this:
  642.  
  643.     /\
  644.    /  \____
  645.   /        \
  646.  /          \
  647.  
  648.  |  | |   |  |
  649.   1  2  3   4
  650.  
  651.   Stages 1, 2, and 3 would be in the ATAK data, like so:
  652.  
  653.   ;Stage 1
  654.   dc.w  100       ;take 100ms
  655.   dc.l  $00004000 ;go to this volume
  656.   dc.w  100
  657.   dc.l  $00008000
  658.   dc.w  100
  659.   dc.l  $0000C000
  660.   dc.w  100
  661.   dc.l  $00010000 ;the "peak" of our attack is full volume
  662.   ;Stage 2
  663.   dc.w  100
  664.   dc.l  $0000C000 ;back off to this level
  665.   dc.l  100
  666.   dc.l  $00008000 ;this is where we hold (SUSTAIN) until the note is turned
  667.                   ;off. (We are now holding at stage 3)
  668.  
  669.   Now the RLSE data would specify stage 4 as follows:
  670.   dc.w  100
  671.   dc.l  $00004000
  672.   dc.w  100
  673.   dc.l  $00000000 ;the volume is 0
  674.  
  675.         ===============ADDITIONAL USER DATA SECTION=================
  676.  
  677.   There is a provision for storing user data. This is where an application
  678. can store Amiga hardware info, or other, application specific info. The value
  679. of typeOfData tells what kind of data is stored here. The current types are:
  680.  
  681. #define SPECIFIC 0
  682. #define VOLMOD   1
  683. #define PERMOD   2
  684. #define LOOPING  3
  685.  
  686.  SPECIFIC (0) - application specific data. It should be stored
  687.                 in a format that some application can immediately
  688.                 recognize. (i.e. a "format within" the SAMP format)
  689.                 If the typeOfData is SPECIFIC, and an application
  690.                 doesn't find some sort of header that it can re-
  691.                 cognize, it should conclude that this data was
  692.                 put there by "someone else", and ignore the data.
  693.  
  694.  VOLMOD (1) -   This data is for volume modulation of an Amiga
  695.                 channel as described by the ADKCON register. This
  696.                 data will be sent to the modulator channel of the
  697.                 channel set to play the wave.
  698.  
  699.  PERMOD (2) -   This data is for period modulation of an Amiga
  700.                 channel as described by the ADKCON register. This
  701.                 data will be sent to the modulator channel of the
  702.                 channel set to play the wave.
  703.  
  704.  LOOPING (3) -  This contains more looping points for the sample.
  705.                 There are some samplers that allow more than just
  706.                 one loop (Casio products primarily). Additional
  707.                 looping info can be stored in this format:
  708.  
  709.                UWORD numOfLoops;  /* number of loop points to follow */
  710.  
  711.                ULONG StartLoop1,  /* BYTE offset from the beginning of
  712.                                     the sample to the start of loop1 */
  713.                EndLoop1,          /* BYTE offset from the beginning of
  714.                                     the sample to the end of loop1 */
  715.  
  716.                StartLoop2,        /* ...etc */
  717.  
  718.           =========Converting Midi Sample Dump to SAMP=========
  719.  
  720.   SEMANTICS: When MIDI literature talks about a sample, usually it means a
  721. collection of many sample points that make up what we call "a wave".
  722. Therefore, a Midi Sample Dump sends all the sample data that makes up ONE
  723. wave. A SAMP file is designed to hold up to 255 of these waves (midi dumps).
  724.  
  725.   The Midi Sample Dump specifies playback rate only in terms of a sample
  726. PERIOD in nanoseconds. SAMP also expresses playback in terms of samples per
  727. second (frequency). The Amiga needs to see its period rounded to the nearest
  728. microsecond. If you take the sample period field of a Midi sample Dump (the
  729. 8th, 9th, and 10th bytes of the Dump Header LSB first) which we will call
  730. MidiSamplePer, and the sampleRate of a SAMP file, here is the relationship:
  731.  
  732.     sampleRate = (1/MidiSamplePer) x 10E9
  733.  
  734.   Also the number of samples (wave's length) in a Midi Sample Dump (the 11th,
  735. 12th, and 13th bytes of the Dump header) is expressed in WORDS. SAMP's
  736. waveSize is expressed in the number of BYTES. (For the incredibly stupid),
  737. the relationship is:
  738.  
  739.    waveSize = MidiSampleLength x 2
  740.  
  741.   A Midi sample dump's loopStartPoint and loopEndPoint are also in WORDS as
  742. versus the SAMP equivalents expressed in BYTES.
  743.  
  744.    A Midi sample dump's sample number can be 0 to 65535. A SAMP file can hold
  745. up to 255 waves, and their numbers in the playmap must be 1 to 255. (A single,
  746. Midi Sample Dump only sends info on one wave.) When recieving a Midi Sample
  747. Dump, just store the sample number (5th and 6th bytes of the Dump Header LSB
  748. first) in SAMP's midiSampNum field. Then forget about this number until you
  749. need to send the wave back to the Midi instrument from whence it came.
  750.  
  751.   A Midi Dump's loop type can be forward, or forward/backward. Amiga hardware
  752. supports forward only. You should store the Midi Dump's loopType byte here,
  753. but ignore it otherwise until/unless Amiga hardware supports "reading audio
  754. data" in various ways. If so, then the looptype is as follows:
  755.  
  756.     forward = 0, backward/forward = 1
  757.  
  758.   A Midi Dump's sample format byte is the same as SAMP's.
  759.  
  760.   ===================== INTERPRETING THE PLAYMODE ==========================
  761.   playMode specifies how the bytes in the playMap are to be interpreted.
  762.   Remember that a playMap byte of 0 means "No Wave to Play".
  763.  
  764. #define INDEPENDANT 0
  765. #define MULTI       1
  766. #define STEREO      2
  767. #define PAN         3
  768.  
  769.   playMode types:
  770.  
  771.  INDEPENDANT (0) - The four wave #s for a midi note are to be output on
  772.                    Amiga channels 0, 1, 2, and 3 respectively.
  773.  
  774.  MULTI       (1) - The first wave # (first of the four playMap bytes) for a
  775.                    midi note is to be output on any free channel. The other
  776.                    3 wave numbers are ignored. If all four channels are in
  777.                    play, the application can decide whether to "steal" a
  778.                    channel.
  779.  
  780.  STEREO     (2) -  The first wave # (first of the 4 playMap bytes) is to be
  781.                    output of the Left stereo jack (channel 1 or 3) and the
  782.                    second wave number (the second of the 4 playMap bytes) is
  783.                    to be output the Right jack (channel 2 or 4). The other 2
  784.                    wave numbers are ignored.
  785.  
  786.  PAN        (3) -  This is just like STEREO except that the volume of wave 1
  787.                    should start at its initial volume (midi velocity) and
  788.                    fade to 0. At the same rate, wave 2 should start at 0
  789.                    volume and rise to wave #1's initial level. The net
  790.                    effect is that the waves "cross" from Left to Right in
  791.                    the stereo field. This is most effective when the wave
  792.                    numbers are the same. (ie the same wave) The application
  793.                    program should set the rate. Also, the application can
  794.                    reverse the stereo direction (ie Right to Left fade).
  795.  
  796.   The most important wave # to be played back by a midi note should be the
  797. first of the four playMap bytes. The second playMap byte should be a defined
  798. wave number as well (even if it is deliberately set to the same value as the
  799. first byte). This insures that all 4 playModes will have some effect on a
  800. given SAMP file. Also, an application should allow the user to change the
  801. playMode at will. The value stored in the SAMP file is only a default or
  802. initial set-up condition.
  803.  
  804.   =================== MAKING A TRANSPOSE TABLE =====================
  805.  
  806.  In order to allow a wave to playback over a range of musical notes, (+/-
  807. semitones), its playback rate must be raised or lowered by a set amount.
  808. From one semitone to the next, this set amount is by a factor of the 12th
  809. root of 2 (assuming a western, equal-tempered scale). Here is a table that
  810. shows what factor would need to be multiplied by the sampling rate in order
  811. to transpose the wave's pitch.
  812.  
  813.   Pitch in relation to the Root     Multiply Rate by this amount
  814.  -------------------------------   ------------------------------
  815.    DOWN 6     semitones              0.5
  816.    DOWN 5 1/2 semitones              0.529731547
  817.    DOWN 5     semitones              0.561231024
  818.    DOWN 4 1/2 semitones              0.594603557
  819.    DOWN 4     semitones              0.629960525
  820.    DOWN 3 1/2 semitones              0.667419927
  821.    DOWN 3     semitones              0.707106781
  822.    DOWN 2 1/2 semitones              0.749153538
  823.    DOWN 2     semitones              0.793700526
  824.    DOWN 1 1/2 semitones              0.840896415
  825.    DOWN 1     semitones              0.890898718
  826.    DOWN 1/2   semitone               0.943874312
  827. ORIGINAL_PITCH                       1.0           /* rootnote's pitch */
  828.    UP   1/2   semitone               1.059463094
  829.    UP   1     semitones              1.122562048
  830.    UP   1 1/2 semitones              1.189207115
  831.    UP   2     semitones              1.259921050
  832.    UP   2 1/2 semitones              1.334839854
  833.    UP   3     semitones              1.414213562
  834.    UP   3 1/2 semitones              1.498307077
  835.    UP   4     semitones              1.587401052
  836.    UP   4 1/2 semitones              1.681792830
  837.    UP   5     semitones              1.781797436
  838.    UP   5 1/2 semitones              1.887748625
  839.    UP   6     semitones              2
  840.  
  841.   For example, if the wave's sampleRate is 18000 hz, and you wish to play
  842. the wave UP 1 semitone, then the playback rate is:
  843.  
  844.    18000 x 1.122562048 = 20206.11686 hz
  845.  
  846.   The sampling period for the Amiga is therefore:
  847.  
  848.      (1/20206.11686)/.279365 = .000177151
  849.  
  850.  and to send it to the Audio Device, it is rounded and expressed in micro-
  851. seconds: 177
  852.  
  853.   Obviously, this involves floating point math which can be time consuming
  854. and impractical for outputing sound in real-time. A better method is to con-
  855. struct a transpose table that contains the actual periods already calculated
  856. for every semitone. The drawback of this method is that you need a table for
  857. EVERY DIFFERENT sampleRate in the SAMP file. If all the sampleRates in the
  858. file happened to be the same, then only one table would be needed. Let's
  859. assume that this is the case, and that the sampleRate = 18000 hz. Here is a
  860. table containing enough entries to transpose the waves +/- 6 semitones.
  861.  
  862.   Pitch in relation to the Root     The Amiga Period (assuming rate = 18000 hz)
  863.  -------------------------------   ------------------------------
  864. Transposition_table[TRANS_TABLE_SIZE]={
  865. /* DOWN 6     semitones  */            398,
  866. /* DOWN 5 1/2 semitones  */            375,
  867. /* DOWN 5     semitones  */            354,
  868. /* DOWN 4 1/2 semitones  */            334,
  869. /* DOWN 4     semitones  */            316,
  870. /* DOWN 3 1/2 semitones  */            298,
  871. /* DOWN 3     semitones  */            281,
  872. /* DOWN 2 1/2 semitones  */            265,
  873. /* DOWN 2     semitones  */            251,
  874. /* DOWN 1 1/2 semitones  */            236,
  875. /* DOWN 1     semitones  */            223,
  876. /* DOWN 1/2   semitone   */            211,
  877. /* ORIGINAL_PITCH        */            199,      /* rootnote's pitch */
  878. /* UP   1/2   semitone   */            187,
  879. /* UP   1     semitones  */            177,
  880. /* UP   1 1/2 semitones  */            167,
  881. /* UP   2     semitones  */            157,
  882. /* UP   2 1/2 semitones  */            148,
  883. /* UP   3     semitones  */            141,
  884. /* UP   3 1/2 semitones  */            133,
  885.  /* Since the minimum Amiga period = 127 the following
  886.     are actually out of range. */
  887. /* UP   4     semitones  */            125,
  888. /* UP   4 1/2 semitones  */            118,
  889. /* UP   5     semitones  */            112,
  890. /* UP   5 1/2 semitones  */            105,
  891. /* UP   6     semitones  */            99   };
  892.  
  893.  
  894.   Let's assume that (according to the playMap) midi note #40 is set to play
  895. wave number 3. Upon examining wave 3's structure, we discover that the
  896. sampleRate = 18000, and the rootNote = 38. Here is how the Amiga sampling
  897. period is calulated using the above 18000hz "transpose chart" in C:
  898.   /* MidiNoteNumber is the received midi note's number (here 40) */
  899.  
  900.   #define ORIGINAL_PITCH     TRANS_TABLE_SIZE/2 + 1
  901. /* TRANS_TABLE_SIZE is the number of entries in the transposition table
  902.    (dynamic, ie this can change with the application) */
  903.  
  904.   transposeAmount = (LONG) (MidiNoteNumber - rootNote); /* make it a SIGNED LONG */
  905.   amigaPeriod     = Transposition_table[ORIGINAL_PITCH + transposeAmount];
  906.  
  907.  
  908.   In assembly, the 18000hz transpose chart and above example would be:
  909.  
  910. Table       dc.w  398
  911.             dc.w  375
  912.             dc.w  354
  913.             dc.w  334
  914.             dc.w  316
  915.             dc.w  298
  916.             dc.w  281
  917.             dc.w  265
  918.             dc.w  251
  919.             dc.w  236
  920.             dc.w  223
  921.             dc.w  211
  922. ORIGINAL_PITCH  dc.w  199   ; rootnote's pitch
  923.             dc.w  187
  924.             dc.w  177
  925.             dc.w  167
  926.             dc.w  157
  927.             dc.w  148
  928.             dc.w  141
  929.             dc.w  133
  930.  ; Since the minimum Amiga period = 127, the following
  931.  ; are actually out of range.
  932.             dc.w  125
  933.             dc.w  118
  934.             dc.w  112
  935.             dc.w  105
  936.             dc.w  99
  937.  
  938.   lea     ORIGINAL_PITCH,a0
  939.   move.b  MidiNoteNumber,d0  ;the received note number
  940.   sub.b   rootNote,d0        ;subtract the wave's root note
  941.   ext.w   d0
  942.   ext.l   d0                 ;make it a signed LONG
  943.   add.l   d0,d0              ;x 2 in order to fetch a WORD
  944.   adda.l  d0,a0
  945.   move.w  (a0),d0            ;the Amiga Period (WORD)
  946.  
  947.   Note that these examples don't check to see if the transpose amount is
  948. beyond the number of entries in the transpose table. Nor do they check if
  949. the periods in the table are out of range of the Amiga hardware.
  950.  
  951.     ===================== MAKING THE VELOCITY TABLE ======================
  952.  
  953.   The 16 entries in the velocity table should be within the oneShot portion of
  954. the sample (ie not in the looping portion). THe first offset, velStartTable[0]
  955. should be set to zero (in order to play back from the beginning of the data).
  956. The subsequent values should be increasing numbers. If you are using a graphic
  957. editor, try choosing offsets that will keep you within the initial attack
  958. portion of the wave. In practice, these values will be relatively close
  959. together within the wave. Always set the offsets so that when they are added
  960. to the sample start point, the resulting address points to a sample value of
  961. zero (a zero crossing point). This will eliminate pops and clicks at the 
  962. beginning of the playback.
  963.  
  964.   In addition, the start of the wave should be on a sample with a value of
  965. zero. The last sample of the oneShot portion and the first sample of the
  966. looping portion should be approximately equal, (or zero points). The same is
  967. true of the first and last samples of the looping portion. Finally, try to
  968. keep the slopes of the end of the oneShot, the beginning of the looping, and
  969. the end of the looping section, approximately equal. All this will eliminate
  970. noise on the audio output and provide "seamless" looping.
  971.  
  972.   ======================== THE INSTRUMENT TYPE ==========================
  973.  
  974.   Many SMUS players search for certain instruments by name. Not only is this
  975. slow (comparing strings), but if the exact name can't be found, then it is
  976. very difficult and time-consuming to search for a suitable replacement. For
  977. this reason, many SMUS players resort to "default" instruments even if these
  978. are nothing like the desired instruments. The instrumentType byte in each
  979. waveHeader is meant to be a numeric code which will tell an SMUS player
  980. exactly what the instrument is. In this way, the SMUS player can search for
  981. the correct "type" of instrument if it can't find the desired name. The type
  982. byte is divided into 2 nibbles (4 bits for you C programmers) with the low
  983. 4 bits representing the instrument "family" as follows:
  984.  
  985.  1 = STRING, 2 = WOODWIND, 3 = KEYBOARD, 4 = GUITAR, 5 = VOICE, 6 = DRUM1,
  986.  7 = DRUM2,  8 = PERCUSSION1, 9 = BRASS1, A = BRASS2, B = CYMBAL, C = EFFECT1,
  987.  D = EFFECT2, E = SYNTH, F are undefined at this time
  988.  
  989.  Now, the high nibble describes the particular type within that family.
  990.  
  991.  For the STRING family, the high nibble is as follows:
  992.  
  993.  1 = VIOLIN BOW, 2 = VIOLIN PLUCK, 3 = VIOLIN GLISSANDO, 4 = VIOLIN TREMULO,
  994.  5 = VIOLA BOW, 6 = VIOLA PLUCK, 7 = VIOLA GLIS, 8 = VIOLA TREM, 9 = CELLO
  995.  BOW, A = CELLO PLUCK, B = CELLO GLIS, C = CELLO TREM, D = BASS BOW, E =
  996.  BASS PLUCK (jazz bass), F = BASS TREM
  997.  
  998.  For the BRASS1 family, the high nibble is as follows:
  999.  
  1000.  1 = BARITONE SAX, 2 = BARI GROWL, 3 = TENOR SAX, 4 = TENOR GROWL, 5 = ALTO
  1001.  SAX, 6 = ALTO GROWL, 7 = SOPRANO SAX, 8 = SOPRANO GROWL, 9 = TRUMPET, A =
  1002.  MUTED TRUMPET, B = TRUMPET DROP, C = TROMBONE, D = TROMBONE SLIDE, E =
  1003.  TROMBONE MUTE
  1004.  
  1005.  For the BRASS2 family, the high nibble is as follows:
  1006.  
  1007.  1 = FRENCH HORN, 2 = TUBA, 3 = FLUGAL HORN, 4 = ENGLISH HORN
  1008.  
  1009.  For the WOODWIND family, the high nibble is as follows:
  1010.  
  1011.  1 = CLARINET, 2 = FLUTE, 3 = PAN FLUTE, 4 = OBOE, 5 = PICCOLO, 6 = RECORDER,
  1012.  7 = BASSOON, 8 = BASS CLARINET, 9 = HARMONICA
  1013.  
  1014.  For the KEYBOARD family, the high nibble is as follows:
  1015.  
  1016.  1 = GRAND PIANO, 2 = ELEC. PIANO, 3 = HONKYTONK PIANO, 4 = TOY PIANO, 5 =
  1017.  HARPSICHORD, 6 = CLAVINET, 7 = PIPE ORGAN, 8 = HAMMOND B-3, 9 = FARFISA
  1018.  ORGAN, A = HARP
  1019.  
  1020.  For the DRUM1 family, the high nibble is as follows:
  1021.  
  1022.  1 = KICK, 2 = SNARE, 3 = TOM, 4 = TIMBALES, 5 = CONGA HIT, 6 = CONGA SLAP,
  1023.  7 = BRUSH SNARE, 8 = ELEC SNARE, 9 = ELEC KICK, A = ELEC TOM, B = RIMSHOT,
  1024.  C = CROSS STICK, D = BONGO, E = STEEL DRUM, F = DOUBLE TOM
  1025.  
  1026.  For the DRUM2 family, the high nibble is as follows:
  1027.  
  1028.  1 = TIMPANI, 2 = TIMPANI ROLL, 3 = LOG DRUM
  1029.  
  1030.  For the PERCUSSION1 family, the high nibble is as follows:
  1031.  
  1032.  1 = BLOCK, 2 = COWBELL, 3 = TRIANGLE, 4 = TAMBOURINE, 5 = WHISTLE, 6 =
  1033.  MARACAS, 7 = BELL, 8 = VIBES, 9 = MARIMBA, A = XYLOPHONE, B = TUBULAR BELLS,
  1034.  C = GLOCKENSPEIL
  1035.  
  1036.  For the CYMBAL family, the high nibble is as follows:
  1037.  
  1038.  1 = CLOSED HIHAT, 2 = OPEN HIHAT, 3 = STEP HIHAT, 4 = RIDE, 5 = BELL CYMBAL,
  1039.  6 = CRASH, 7 = CHOKE CRASH, 8 = GONG, 9 = BELL TREE, A = CYMBAL ROLL
  1040.  
  1041.  For the GUITAR family, the high nibble is as follows:
  1042.  
  1043.  1 = ELECTRIC, 2 = MUTED ELECTRIC, 3 = DISTORTED, 4 = ACOUSTIC, 5 = 12-STRING,
  1044.  6 = NYLON STRING, 7 = POWER CHORD, 8 = HARMONICS, 9 = CHORD STRUM, A = BANJO,
  1045.  B = ELEC. BASS, C = SLAPPED BASS, D = POPPED BASS, E = SITAR, F = MANDOLIN
  1046.  (Note that an acoustic picked bass is found in the STRINGS - Bass Pluck)
  1047.  
  1048.  For the VOICE family, the high nibble is as follows:
  1049.  
  1050.  1 = MALE AHH, 2 = FEMALE AHH, 3 = MALE OOO, 4 = FEMALE OOO, 5 = FEMALE
  1051.  BREATHY, 6 = LAUGH, 7 = WHISTLE
  1052.  
  1053.  For the EFFECTS1 family, the high nibble is as follows:
  1054.  
  1055.  1 = EXPLOSION, 2 = GUNSHOT, 3 = CREAKING DOOR OPEN, 4 = DOOR SLAM, 5 = DOOR
  1056.  CLOSE, 6 = SPACEGUN, 7 = JET ENGINE, 8 = PROPELLER, 9 = HELOCOPTER, A =
  1057.  BROKEN GLASS, B = THUNDER, C = RAIN, D = BIRDS, E = JUNGLE NOISES, F =
  1058.  FOOTSTEP
  1059.  
  1060.  For the EFFECTS2 family, the high nibble is as follows:
  1061.  
  1062.  1 = MACHINE GUN, 2 = TELEPHONE, 3 = DOG BARK, 4 = DOG GROWL, 5 = BOAT
  1063.  WHISTLE, 6 = OCEAN, 7 = WIND, 8 = CROWD BOOS, 9 = APPLAUSE, A = ROARING
  1064.  CROWDS, B = SCREAM, C = SWORD CLASH, D = AVALANCE, E = BOUNCING BALL,
  1065.  F = BALL AGAINST BAT OR CLUB
  1066.  
  1067.  For the SYNTH family, the high nibble is as follows:
  1068.  
  1069.  1 = STRINGS, 2 = SQUARE, 3 = SAWTOOTH, 4 = TRIANGLE, 5 = SINE, 6 = NOISE
  1070.  
  1071.   So, for example if a wave's type byte was 0x26, this would be a SNARE DRUM.
  1072. If a wave's type byte is 0, then this means "UNKNOWN" instrument.
  1073.  
  1074.   ===================== THE ORDER OF THE CHUNKS =========================
  1075.  
  1076.  The SAMP header obviously must be first in the file, followed by the MHDR
  1077. chunk. After this, the ANNO, (c), AUTH and NAME chunks may follow in any
  1078. order, though none of these need appear in the file at all. THe BODY chunk
  1079. must be last.
  1080.  
  1081.   ============ WHY DOES ANYONE NEED SUCH A COMPLICATED FILE ==============
  1082.                  (or "What's wrong with 8SVX anyway?")
  1083.  
  1084.   In a nutshell, 8SVX is not adequate for professional music sampling. First
  1085. of all, it is nearly impossible to use multi-sampling (utilizing several,
  1086. different samples of any instrument throughout its musical range). This very
  1087. reason alone makes it impossible to realistically reproduce a musical in-
  1088. strument, as none in existance (aside from an electronic organ) uses inter-
  1089. polations of a single wave to create its musical note range.
  1090.   Also, stretching a sample out over an entire octave range does grotesque
  1091. (and VERY unmusical) things to such elements as the overtone structure,
  1092. wind/percussive noises, the instrument's amplitude envelope, etc. The 8SVX
  1093. format is designed to stretch the playback in exactly this manner.
  1094.   8SVX ignores MIDI which is the de facto standard of musical data transmission.
  1095.   8SVX does not allow storing data for features that are commonplace to pro-
  1096. fessional music samplers. Such features are: velocity sample start, separate
  1097. filter and envelopes for each sample, separate sampling rates, and various
  1098. playback modes like stereo sampling and panning.
  1099.   SAMP attempts to remedy all of these problems with a format that can be
  1100. used by a program that simulates these professional features in software. The
  1101. format was inspired by the capabilities of the following musical products:
  1102.  
  1103.   EMU's                 EMAX, EMULATOR
  1104.   SEQUENTIAL CIRCUIT's  PROPHET 2000, STUDIO 440
  1105.   ENSONIQ's             MIRAGE
  1106.   CASIO's               FZ-1
  1107.   OBERHEIM's            DPX
  1108.   YAMAHA                TX series
  1109.  
  1110.    So why does the Amiga need the SAMP format? Because professional musician's
  1111. are buying computers. With the firm establishment of MIDI, musician's are
  1112. buying and using a variety of sequencers, patch editors, and scoring programs.
  1113. It is now common knowledge amoung professional musicians that the Amiga
  1114. lags far behind IBM clones, Macintosh, and Atari ST computers in both music
  1115. software and hardware support. Both Commodore and the current crop of short-
  1116. sighted 3rd party Amiga developers are pigeon-holing the Amiga as "a video
  1117. computer". It is important for music software to exploit whatever capabili-
  1118. ties the Amiga offers before the paint and animation programs, genlocks,
  1119. frame-grabbers, and video breadboxes are the only applications available
  1120. for the Amiga. Hopefully, this format, with the SAMP and music libraries will
  1121. make it possible for Amiga software to attain the level of professionalism
  1122. that the other machines now boast, and the Amiga lacks.
  1123.