home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Extras / IFF / IFF_Forms / SAMP.doc < prev    next >
Encoding:
Text File  |  1993-03-01  |  54.0 KB  |  1,175 lines

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