home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 390.lha / SampLibrary / samp.doc.pp / samp.doc
Encoding:
Text File  |  1990-07-01  |  54.1 KB  |  1,176 lines

  1.                        IFF FORM "SAMP" Sampled Sound
  2.  
  3.  Date:   Dec 3,1989
  4.  From:   Jim Fiore and Jeff Glatt, dissidents
  5.  Status: Finally under consideration by CATS thanks to Darius
  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, with example applications.
  29.  
  30.   SEMANTICS: When MIDI literature talks about a sample, usually it means a
  31. collection of many sample points that make up what we call a "wave".
  32.  
  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. If 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.  
  65.           =================THE "SAMP" HEADER================
  66.  
  67.  At the very beginning of a sound file is the "SAMP" header. This is used to
  68. determine if the disk file is indeed a SAMP sound file. It's attributes are
  69. as follows:
  70.  
  71. #define ID_SAMP MakeID('S','A','M','P')
  72.  
  73.   In assembly, this looks like:
  74.  
  75.       CNOP 0,2  ;word-align
  76.  
  77. TypeID       dc.b  'FORM'  ;could be 'LIST' or 'CAT '
  78. sizeOfChunks dc.l  [sizes of all subsequent chunks summed]
  79. SAMP         dc.b  'SAMP'
  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. struct MHDRChunk {
  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.    };
  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. struct waveHeader {
  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.  };
  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.     Presently, sample data is stored in linear format (as per the MIDI spec). 
  391. Currently, all music samplers, regardless of their internal method of playing
  392. sample data must transmit and expect to receive sample dumps in a linear
  393. format. It is up to each device to translate the linear format into its own
  394. compression scheme. For example, if you are using an 8 bit compression scheme
  395. that yields a 14 bit linear range, you should convert each sample data BYTE
  396. to a decom- pressed linear WORD when you save a sound file. Set the MHDR's
  397. Format to 14. It is up to the application to do its own compression upon
  398. loading a file. The midi spec was set up this way because musical samplers
  399. need to pass sample data between each other, and computers (via a midi
  400. interface). Since there are almost as many data compression schemes on the
  401. market as there are musical products, it was decided that all samplers should
  402. expect data received over midi to be in LINEAR format. It seems logical to
  403. store it this way on disc as well, however, the Flags field may be used in the 
  404. future to indicate a form of data compression to help reduce disc storage
  405. requirements. ( In other words, the present version of samp.library does not
  406. use compression, although this may be an option in the future. ) The
  407. continuation Flag hleps solve the problem of storage as well.
  408.  
  409.   Since the 68000 can only perform math on BYTES, WORDS, or LONGS, it has
  410. been decided that a sample point should be converted to one of these sizes
  411. when saved in SAMP as follows:
  412.  
  413.  ORIGINAL significant bits          SAMP sample point size
  414.  ­­­­­­­­­­­­­­­­­­­­­­­­­          ­­­­­­­­­­­­­­­­­­­­­­
  415.             8                               BYTE
  416.           9 to 16                           WORD
  417.           17 to 28                          LONG
  418.  
  419.   Furthermore, the significant bits should be left-justified since it is
  420. easier to perform math on the samples.
  421.  
  422.   So, for example, an 8 bit sample point (like 8SVX) would be saved as a
  423. BYTE with all 8 bits being significant. The MHDR's Format = 8. No
  424. conversion is necessary.
  425.  
  426.   A 12 bit sample point should be stored as a WORD with the significant bits
  427. being numbers 4 to 15. (i.e shift the 12-bit WORD 4 places to the left). Bits
  428. 0, 1, 2 and 3 may be zero (unless some 16-bit math was performed and you wish to
  429. save these results). The MHDR's Format = 12. In this way, the sample
  430. may be loaded and manipulated as a 16-bit wave, but when transmitted via
  431. midi, it can be converted back to 12 bits (rounded and shifted right by 4).
  432.  
  433.   A 16 bit sample point would be saved as a WORD with all 16 bits being
  434. significant. The MHDR's Format = 16. No conversion is necessary.
  435.  
  436.  
  437.           ============== The waveHeader explained ==============
  438.  
  439.    The WaveSize is, as stated, the number of BYTES in the wave's sample table.
  440. If your sample data consisted of the following 8 bit samples:
  441.  
  442.     BYTE  100,-90,80,-60,30,35,40,-30,-35,-40,00,12,12,10
  443.  
  444.  then WaveSize = 14. (PAD THE DATA OUT TO AN EVEN NUMBER OF BYTES!)
  445.  
  446.   The MidiSampNum is ONLY used to hold the sample number received from a MIDI
  447. Sample Dump. It has no bearing on where the wave should be placed in a SAMP
  448. file. Also, the wave numbers in the PlayMap are between 1 to 255, with 1 being
  449. the number of the first wave in the file. Remember that a wave number of 0 is
  450. reserved to mean "no wave to play back". Likewise, the LoopType is only used
  451. to hold info from a MIDI sample dump.
  452.  
  453.    The InsType is explained at the end of this document. Often it will be set
  454. to 0.
  455.  
  456.    The RootNote is the Midi Note number that will play the wave back at it's
  457. original, recorded pitch. For example, consider the following excerpt of a
  458. PlayMap:
  459.  
  460.   PlayMap  {2,0,0,4       /* Midi Note #0 channel assignment */
  461.             4,100,1,0     /* Midi Note #1    "        "  */
  462.             1,4,0,0       /* Midi Note #2    "        "  */
  463.             60,2,1,1...}  /* Midi Note #3    "        "  */
  464.  
  465.   Notice that Midi Notes 0, 1, and 2 are all set to play wave number 4 (on
  466. Amiga channels 3, 0, and 1 respectively). If we set wave 4's RootNote = 1,
  467. then receiving Midi Note number 1 would play back wave 4 (on Amiga channel 0)
  468. at it's original pitch. If we receive a Midi Note number 0, then wave 4 would
  469. be played back on channel 3) a half step lower than it's original pitch. If we
  470. receive Midi Note number 2, then wave 4 would be played (on channel 1) a half
  471. step higher than it's original pitch. If we receive Midi Note number 3, then
  472. wave 4 would not be played at all because it isn't specified in the PlayMap
  473. bytes for Midi Note number 3.
  474.  
  475.   The Rate is the number of samples per second of the original pitch.
  476. For example, if Rate = 20000, then to play the wave at it's original
  477. pitch, the sampling period would be:
  478.  
  479.      (1/20000)/.279365 = .000178977
  480.  
  481. #define AUDIO_HARDWARE_FUDGE .279365
  482.  
  483. where .279365 is the Amiga Fudge Factor (a hardware limitation). Since the
  484. amiga needs to see the period in terms of microseconds, move the decimal place
  485. to the right 6 places and our sampling period = 179 (rounded to an integer).
  486. In order to play the wave at higher or lower pitches, one would need to
  487. "transpose" this period value. By specifying a higher period value, the Amiga
  488. will play back the samples slower, and a lower pitch will be achieved. By
  489. specifying a lower period value, the amiga will play back the sample faster,
  490. and a higher pitch will be achieved. By specifying this exact period, the wave
  491. will be played back exactly "as it was recorded (sampled)". ("This period is
  492. JUST RIGHT!", exclaimed GoldiLocks.) Later, a method of transposing pitch will
  493. be shown using a "look up" table of periods. This should prove to be the
  494. fastest way to transpose pitch, though there is nothing in the SAMP format
  495. that compels you to do it this way.
  496.  
  497.   The LoopStart is a BYTE offset from the beginning of the wave to where
  498. the looping portion of the wave begins. For example, if SampleData points to
  499. the start of the wave, then SampleData + LoopStart is the start address
  500. of the looping portion. In 8SVX, the looping portion was referred to as
  501. repeatHiSamples. The data from the start of the wave up to the start of the
  502. looping portion is the oneShot portion of the wave. LoopEnd is a BYTE
  503. offset from the beginning of the wave to where the looping portion ends. This
  504. might be the very end of the wave in memory, or perhaps there might be still
  505. more data after this point. You can choose to ignore this "trailing" data and
  506. play back the two other portions of the wave just like an 8SVX file (except
  507. that there are no other interpolated octaves of this wave).
  508.  
  509.   VelTable contains 16 BYTE offsets from the beginning of the wave. Each
  510. successive value should be greater (or equal to) the preceding value. If
  511. VelStart = POSITIVE (64), then for each 8 increments in Midi Velocity
  512. above 0, you move UP in the table, add this offset to the wave's beginning
  513. address (start of oneShot), and start playback at that address. Here is a 
  514. table relating received midi note-on velocity vs. start playback address for
  515. POSITIVE VelStart. SamplePtr points to the beginning of the sample.
  516.  
  517.  If midi velocity = 0, then don't play a sample, this is a note off
  518.  If midi velocity = 1 to 7, then start play at SamplePtr + VelTable[0]
  519.  If midi velocity = 8 to 15, then start at SamplePtr + VelTable[1]
  520.  If midi velocity = 16 to 23, then start at SamplePtr + VelTable[2]
  521.  If midi velocity = 24 to 31, then start at SamplePtr + VelTable[3]
  522.  If midi velocity = 32 to 39, then start at SamplePtr + VelTable[4]
  523.  If midi velocity = 40 to 47, then start at SamplePtr + VelTable[5]
  524.  If midi velocity = 48 to 55, then start at SamplePtr + VelTable[6]
  525.  If midi velocity = 56 to 63, then start at SamplePtr + VelTable[7]
  526.  If midi velocity = 64 to 71, then start at SamplePtr + VelTable[8]
  527.  If midi velocity = 72 to 79, then start at SamplePtr + VelTable[9]
  528.  If midi velocity = 80 to 87, then start at SamplePtr + VelTable[10]
  529.  If midi velocity = 88 to 95, then start at SamplePtr + VelTable[11]
  530.  If midi velocity = 96 to 103, then start at SamplePtr + VelTable[12]
  531.  If midi velocity = 104 to 111, then start at SamplePtr + VelTable[13]
  532.  If midi velocity = 112 to 119, then start at SamplePtr + VelTable[14]
  533.  If midi velocity = 120 to 127, then start at SamplePtr + VelTable[15]
  534.  
  535. We don't want to specify a scale factor and use integer division to find the
  536. sample start. This would not only be slow, but also, it could never be certain
  537. that the resulting sample would be a zero crossing if the start point is calcu-
  538. lated "on the fly". The reason for having a table is so that the offsets can be
  539. be initially set on zero crossings via an editor. This way, no audio "clicks"
  540. guaranteed. This table should provide enough resolution.
  541.  
  542.    If VelStart = NEGATIVE (128), then for each 8 increments in midi
  543. velocity, you start from the END of VelTable, and work backwards. Here
  544. is a table for NEGATIVE velocity start.
  545.  
  546.  If midi velocity = 0, then don't play a sample, this is a note off
  547.  If midi velocity = 1 to 7, then start play at SamplePtr + VelTable[15]
  548.  If midi velocity = 8 to 15, then start at SamplePtr + VelTable[14]
  549.  If midi velocity = 16 to 23, then start at SamplePtr + VelTable[13]
  550.  If midi velocity = 24 to 31, then start at SamplePtr + VelTable[12]
  551.  If midi velocity = 32 to 39, then start at SamplePtr + VelTable[11]
  552.  If midi velocity = 40 to 47, then start at SamplePtr + VelTable[10]
  553.  If midi velocity = 48 to 55, then start at SamplePtr + VelTable[9]
  554.  If midi velocity = 56 to 63, then start at SamplePtr + VelTable[8]
  555.  If midi velocity = 64 to 71, then start at SamplePtr + VelTable[7]
  556.  If midi velocity = 72 to 81, then start at SamplePtr + VelTable[6]
  557.  If midi velocity = 80 to 87, then start at SamplePtr + VelTable[5]
  558.  If midi velocity = 88 to 95, then start at SamplePtr + VelTable[4]
  559.  If midi velocity = 96 to 103, then start at SamplePtr + VelTable[3]
  560.  If midi velocity = 104 to 111, then start at SamplePtr + VelTable[2]
  561.  If midi velocity = 112 to 119, then start at SamplePtr + VelTable[1]
  562.  If midi velocity = 120 to 127, then start at SamplePtr + VelTable[0]
  563.  
  564.  In essence, increasing midi velocity starts playback "farther into" the wave
  565. for POSITIVE VelStart. Increasing midi velocity "brings the start point
  566. back" toward the beginning of the wave for NEGATIVE VelStart.
  567.  
  568.  If VelStart is set to NONE (0), then the wave's playback start should
  569. not be affected by the table of offsets.
  570.  
  571.  What is the use of this feature? As an example, when a snare drum is hit with
  572. a soft volume, its initial attack is less pronounced than when it is struck
  573. hard. You might record a snare being hit hard. By setting VelStart to a
  574. NEGATIVE value and setting up the offsets in the Table, a lower midi velocity
  575. will "skip" the beginning samples and thereby tend to soften the initial
  576. attack. In this way, one wave yields a true representation of its instrument
  577. throughout its volume range. Furthermore, stringed and plucked instruments
  578. (violins, guitars, pianos, etc) exhibit different attacks at different
  579. volumes. VelStart makes these kinds of waves more realistic via a software
  580. implementation. Also, an application program can allow the user to enable/
  581. disable this feature. See the section "Making the Velocity Table" for info on
  582. how to best choose the 16 table values.
  583.  
  584.  
  585.         =========MIDI VELOCITY vs. AMIGA CHANNEL VOLUME============
  586.  
  587.  The legal range for Midi Velocity bytes is 0 to 127. (A midi velocity of 0
  588.  should ALWAYS be interpreted as a note off).
  589.  
  590.  The legal range for Amiga channel volume is 0 to 64. Since this is half of
  591.  the midi range, a received midi velocity should be divided by 2 and add 1
  592.  (but only AFTER checking for a received midi velocity of 0).
  593.  
  594.   An example of how to implement a received midi velocity in C:
  595.  
  596.   If ( ReceivedVelocity != 0 && ReceivedVelocity < 128 )
  597.   {   /* the velocity byte of a midi message */
  598.       If (velStart != 0)
  599.       {
  600.           tableEntry = ReceivedVelocity / 8;
  601.           If (velStart == 64)
  602.           {    /* Is it POSITIVE */
  603.                startOfWave = SamplePtr + velTable[tableEntry];
  604.                            /* ^where to find the sample start point */
  605.           }
  606.           If (velStart == 128)
  607.           {    /* Is it NEGATIVE */
  608.                startOfWave = SamplePtr + velTable[15 - tableEntry];
  609.           }
  610.           volume = (receivedVelocity/2 + 1;  /* playback volume */
  611.           /* Now playback the wave */
  612.       }
  613.   }
  614.  
  615.   In assembly,
  616.  
  617.   lea      SampleData,a0        ;the start addr of the sample data
  618.   moveq    #0,d0
  619.   move.b   ReceivedVelocity,d0  ;the velocity byte of a midi message
  620.   beq      A_NoteOff            ;If zero, branch to a routine to
  621.                                 ;process a note-off message.
  622.  
  623.   bmi      Illegal_Vol          ;exit if received velocity > 127
  624.   ;---Check for velocity start feature ON, and direction
  625.   move.b   VelStart,d1
  626.   beq.s    Volume               ;skip the velocity offset routine if 0
  627.   bmi.s    NegativeVel          ;is it NEGATIVE? (128)
  628.  
  629.   ;---Positive velocity offset
  630.   move.l   d0,d1                ;duplicate velocity
  631.   lsr.b    #3,d1                ;divide by 8
  632.   add.b    d1,d1                ;x 2 because we need to fetch a word
  633.   lea      VelTable,a1     ;start at table's HEAD
  634.   adda.l   d1,a1                ;go forward
  635.   move.w   (a1),d1              ;get the velocity offet
  636.   adda.l   d1,a0          ;where to start actual playback
  637.   bra.s    Volume
  638.  
  639. NegativeVel:
  640.   ;---Negative velocity offset
  641.   move.l   d0,d1                ;duplicate velocity
  642.   lsr.b    #3,d1                ;divide by 8
  643.   add.b    d1,d1                ;x 2 because we need to fetch a word
  644.   lea      VelTable+30,a1  ;start at table's END
  645.   suba.l   d1,a1                ;go backwards
  646.   move.w   (a1),d1              ;get the velocity offset
  647.   adda.l   d1,a0          ;where to start actual playback
  648.  
  649.   ;---Convert Midi velocity to an Amiga volume
  650. Volume  lsr.b    #1,d0          ;divide by 2
  651.         addq.b   #1,d0          ;an equivalent Amiga volume
  652.  
  653.  ;---Now a0 and d0 are the address of sample start, and volume
  654.  
  655.  
  656.      ================= AN EGpoint (envelope generator) ================
  657.  
  658.  A single EGpoint is a 6 byte structure as follows:
  659.  
  660. EGpoint1: dc.w ;[the duration in milliseconds]
  661.           dc.l ;[the volume factor - fixed point, 16 bits to the left of the
  662.                ;decimal point and 16 to the right.]
  663.  
  664.   The volume factor is a fixed point where 1.0 ($00010000) represents the
  665.   MAXIMUM volume possible. (i.e. No volume factor should exceed this value.)
  666.   The last EGpoint in the ATAK is always the sustain point. Each EG's volume
  667.   is determined from 0.0, not as a difference from the previous EG's volume.
  668.   I hope that this clears up the ambiguity in the original 8SVX document.
  669.   So, to recreate an amplifier envelope like this:
  670.  
  671.     /\
  672.    /  \____
  673.   /        \
  674.  /          \
  675.  
  676.  |  | |   |  |
  677.   1  2  3   4
  678.  
  679.   Stages 1, 2, and 3 would be in the ATAK data, like so:
  680.  
  681.   ;Stage 1
  682.   dc.w  100       ;take 100ms
  683.   dc.l  $00004000 ;go to this volume
  684.   dc.w  100
  685.   dc.l  $00008000
  686.   dc.w  100
  687.   dc.l  $0000C000
  688.   dc.w  100
  689.   dc.l  $00010000 ;the "peak" of our attack is full volume
  690.   ;Stage 2
  691.   dc.w  100
  692.   dc.l  $0000C000 ;back off to this level
  693.   dc.l  100
  694.   dc.l  $00008000 ;this is where we hold (SUSTAIN) until the note is turned
  695.                   ;off. (We are now holding at stage 3)
  696.  
  697.   Now the RLSE data would specify stage 4 as follows:
  698.   dc.w  100
  699.   dc.l  $00004000
  700.   dc.w  100
  701.   dc.l  $00000000 ;the volume is 0
  702.  
  703.  
  704.         ===============ADDITIONAL USER DATA SECTION=================
  705.  
  706.   There is a provision for storing user data for each wave. This is where an
  707. application can store Amiga hardware info, or other, application specific info.
  708. The waveHeader's USERtype tells what kind of data is stored. The current
  709. types are:
  710.  
  711. #define SPECIFIC 0
  712. #define VOLMOD   1
  713. #define PERMOD   2
  714. #define LOOPING  3
  715.  
  716.  SPECIFIC (0) - application specific data. It should be stored
  717.                 in a format that some application can immediately
  718.                 recognize. (i.e. a "format within" the SAMP format)
  719.                 If the USERtype is SPECIFIC, and an application
  720.                 doesn't find some sort of header that it can re-
  721.                 cognize, it should conclude that this data was
  722.                 put there by "someone else", and ignore the data.
  723.  
  724.  VOLMOD (1) -   This data is for volume modulation of an Amiga
  725.                 channel as described by the ADKCON register. This
  726.                 data will be sent to the modulator channel of the
  727.                 channel set to play the wave.
  728.  
  729.  PERMOD (2) -   This data is for period modulation of an Amiga
  730.                 channel as described by the ADKCON register. This
  731.                 data will be sent to the modulator channel of the
  732.                 channel set to play the wave.
  733.  
  734.  LOOPING (3) -  This contains more looping points for the sample.
  735.                 There are some samplers that allow more than just
  736.                 one loop (Casio products primarily). Additional
  737.                 looping info can be stored in this format:
  738.  
  739.                UWORD numOfLoops;  /* number of loop points to follow */
  740.  
  741.                ULONG StartLoop1,  /* BYTE offset from the beginning of
  742.                                     the sample to the start of loop1 */
  743.                EndLoop1,          /* BYTE offset from the beginning of
  744.                                     the sample to the end of loop1 */
  745.  
  746.                StartLoop2,        /* ...etc */
  747.  
  748.  
  749.           =========Converting Midi Sample Dump to SAMP=========
  750.  
  751.   SEMANTICS: When MIDI literature talks about a sample, usually it means a
  752. collection of many sample points that make up what we call "a wave".
  753. Therefore, a Midi Sample Dump sends all the sample data that makes up ONE
  754. wave. A SAMP file is designed to hold up to 255 of these waves (midi dumps).
  755.  
  756.   The Midi Sample Dump specifies playback rate only in terms of a sample
  757. PERIOD in nanoseconds. SAMP also expresses playback in terms of samples per
  758. second (frequency). The Amiga needs to see its period rounded to the nearest
  759. microsecond. If you take the sample period field of a Midi sample Dump (the
  760. 8th, 9th, and 10th bytes of the Dump Header LSB first) which we will call
  761. MidiSamplePer, and the Rate of a SAMP file, here is the relationship:
  762.  
  763.     Rate = (1/MidiSamplePer) x 10E9
  764.  
  765.   Also the number of samples (wave's length) in a Midi Sample Dump (the 11th,
  766. 12th, and 13th bytes of the Dump header) is expressed in WORDS. SAMP's
  767. WaveSize is expressed in the number of BYTES. (For the incredibly stupid),
  768. the relationship is:
  769.  
  770.    WaveSize = MidiSampleLength x 2
  771.  
  772.   A Midi sample dump's LoopStart point and LoopEnd point are also in WORDS as
  773. versus the SAMP equivalents expressed in BYTES.
  774.  
  775.    A Midi sample dump's sample number can be 0 to 65535. A SAMP file can hold
  776. up to 255 waves, and their numbers in the playmap must be 1 to 255. (A single,
  777. Midi Sample Dump only sends info on one wave.) When recieving a Midi Sample
  778. Dump, just store the sample number (5th and 6th bytes of the Dump Header LSB
  779. first) in SAMP's MidiSampNum field. Then forget about this number until you
  780. need to send the wave back to the Midi instrument from whence it came.
  781.  
  782.   A Midi Dump's loop type can be forward, or forward/backward. Amiga hardware
  783. supports forward only. You should store the Midi Dump's LoopType byte here,
  784. but ignore it otherwise until/unless Amiga hardware supports "reading audio
  785. data" in various ways. If so, then the looptype is as follows:
  786.  
  787.     forward = 0, backward/forward = 1
  788.  
  789.   A Midi Dump's sample format byte is the same as SAMP's.
  790.  
  791.  
  792.   ===================== INTERPRETING THE PLAYMODE ==========================
  793.  
  794.   PlayMode specifies how the bytes in the PlayMap are to be interpreted.
  795.   Remember that a PlayMap byte of 0 means "No Wave to Play".
  796.  
  797. #define INDEPENDANT 0
  798. #define MULTI       1
  799. #define STEREO      2
  800. #define PAN         3
  801.  
  802.   PlayMode types:
  803.  
  804.  INDEPENDANT (0) - The wave #s for a midi note are to be output on
  805.                    Amiga audio channels 0, 1, 2, and 3 respectively.
  806.                    If the NumOfChans is < 4, then only use that many channels.
  807.  
  808.  MULTI       (1) - The first wave # (first of the PlayMap bytes) for a
  809.                    midi note is to be output on any free channel. The other
  810.                    wave numbers are ignored. If all four channels are in
  811.                    play, the application can decide whether to "steal" a
  812.                    channel.
  813.  
  814.  STEREO     (2) -  The first wave # (first of the PlayMap bytes) is to be
  815.                    output of the Left stereo jack (channel 1 or 3) and if
  816.                    there is a second wave number (the second of the PlayMap
  817.                    bytes), it is to be output the Right jack (channel 2 or 4).
  818.                    The other wave numbers are ignored.
  819.  
  820.  PAN        (3) -  This is just like STEREO except that the volume of wave 1
  821.                    should start at its initial volume (midi velocity) and
  822.                    fade to 0. At the same rate, wave 2 should start at 0
  823.                    volume and rise to wave #1's initial level. The net
  824.                    effect is that the waves "cross" from Left to Right in
  825.                    the stereo field. This is most effective when the wave
  826.                    numbers are the same. (ie the same wave) The application
  827.                    program should set the rate. Also, the application can
  828.                    reverse the stereo direction (ie Right to Left fade).
  829.  
  830.   The most important wave # to be played back by a midi note should be the
  831. first of the PlayMap bytes. If the NumOfChans > 1, the second PlayMap byte
  832. should be a defined wave number as well (even if it is deliberately set to the
  833. same value as the first byte). This insures that all 4 PlayModes will have some
  834. effect on a given SAMP file. Also, an application should allow the user to
  835. change the PlayMode at will. The PlayMode stored in the SAMP file is only a
  836. default or initial set-up condition.
  837.  
  838.  
  839.   =================== MAKING A TRANSPOSE TABLE =====================
  840.  
  841.  In order to allow a wave to playback over a range of musical notes, (+/-
  842. semitones), its playback rate must be raised or lowered by a set amount.
  843. From one semitone to the next, this set amount is by a factor of the 12th
  844. root of 2 (assuming a western, equal-tempered scale). Here is a table that
  845. shows what factor would need to be multiplied by the sampling rate in order
  846. to transpose the wave's pitch.
  847.  
  848.   Pitch in relation to the Root     Multiply Rate by this amount
  849.  -------------------------------   ------------------------------
  850.    DOWN 6     semitones              0.5
  851.    DOWN 5 1/2 semitones              0.529731547
  852.    DOWN 5     semitones              0.561231024
  853.    DOWN 4 1/2 semitones              0.594603557
  854.    DOWN 4     semitones              0.629960525
  855.    DOWN 3 1/2 semitones              0.667419927
  856.    DOWN 3     semitones              0.707106781
  857.    DOWN 2 1/2 semitones              0.749153538
  858.    DOWN 2     semitones              0.793700526
  859.    DOWN 1 1/2 semitones              0.840896415
  860.    DOWN 1     semitones              0.890898718
  861.    DOWN 1/2   semitone               0.943874312
  862. ORIGINAL_PITCH                       1.0           /* rootnote's pitch */
  863.    UP   1/2   semitone               1.059463094
  864.    UP   1     semitones              1.122562048
  865.    UP   1 1/2 semitones              1.189207115
  866.    UP   2     semitones              1.259921050
  867.    UP   2 1/2 semitones              1.334839854
  868.    UP   3     semitones              1.414213562
  869.    UP   3 1/2 semitones              1.498307077
  870.    UP   4     semitones              1.587401052
  871.    UP   4 1/2 semitones              1.681792830
  872.    UP   5     semitones              1.781797436
  873.    UP   5 1/2 semitones              1.887748625
  874.    UP   6     semitones              2
  875.  
  876.   For example, if the wave's Rate is 18000 hz, and you wish to play
  877. the wave UP 1 semitone, then the playback rate is:
  878.  
  879.    18000 x 1.122562048 = 20206.11686 hz
  880.  
  881.   The sampling period for the Amiga is therefore:
  882.  
  883.      (1/20206.11686)/.279365 = .000177151
  884.  
  885.  and to send it to the Audio Device, it is rounded and expressed in micro-
  886. seconds: 177
  887.  
  888.   Obviously, this involves floating point math which can be time consuming
  889. and impractical for outputing sound in real-time. A better method is to con-
  890. struct a transpose table that contains the actual periods already calculated
  891. for every semitone. The drawback of this method is that you need a table for
  892. EVERY DIFFERENT Rate in the SAMP file. If all the Rates in the
  893. file happened to be the same, then only one table would be needed. Let's
  894. assume that this is the case, and that the Rate = 18000 hz. Here is a
  895. table containing enough entries to transpose the waves +/- 6 semitones.
  896.  
  897.   Pitch in relation to the Root     The Amiga Period (assuming rate = 18000 hz)
  898.  -------------------------------   ------------------------------
  899. Transposition_table[TRANS_TABLE_SIZE]={
  900. /* DOWN 6     semitones  */            398,
  901. /* DOWN 5 1/2 semitones  */            375,
  902. /* DOWN 5     semitones  */            354,
  903. /* DOWN 4 1/2 semitones  */            334,
  904. /* DOWN 4     semitones  */            316,
  905. /* DOWN 3 1/2 semitones  */            298,
  906. /* DOWN 3     semitones  */            281,
  907. /* DOWN 2 1/2 semitones  */            265,
  908. /* DOWN 2     semitones  */            251,
  909. /* DOWN 1 1/2 semitones  */            236,
  910. /* DOWN 1     semitones  */            223,
  911. /* DOWN 1/2   semitone   */            211,
  912. /* ORIGINAL_PITCH        */            199,      /* rootnote's pitch */
  913. /* UP   1/2   semitone   */            187,
  914. /* UP   1     semitones  */            177,
  915. /* UP   1 1/2 semitones  */            167,
  916. /* UP   2     semitones  */            157,
  917. /* UP   2 1/2 semitones  */            148,
  918. /* UP   3     semitones  */            141,
  919. /* UP   3 1/2 semitones  */            133,
  920.  /* Since the minimum Amiga period = 127 the following
  921.     are actually out of range. */
  922. /* UP   4     semitones  */            125,
  923. /* UP   4 1/2 semitones  */            118,
  924. /* UP   5     semitones  */            112,
  925. /* UP   5 1/2 semitones  */            105,
  926. /* UP   6     semitones  */            99   };
  927.  
  928.  
  929.   Let's assume that (according to the PlayMap) midi note #40 is set to play
  930. wave number 3. Upon examining wave 3's structure, we discover that the
  931. Rate = 18000, and the RootNote = 38. Here is how the Amiga sampling
  932. period is calulated using the above 18000hz "transpose chart" in C:
  933.   /* MidiNoteNumber is the received midi note's number (here 40) */
  934.  
  935.   #define ORIGINAL_PITCH     TRANS_TABLE_SIZE/2 + 1
  936. /* TRANS_TABLE_SIZE is the number of entries in the transposition table
  937.    (dynamic, ie this can change with the application) */
  938.  
  939.   transposeAmount = (LONG) (MidiNoteNumber - rootNote); /* make it a SIGNED LONG */
  940.   amigaPeriod     = Transposition_table[ORIGINAL_PITCH + transposeAmount];
  941.  
  942.  
  943.   In assembly, the 18000hz transpose chart and above example would be:
  944.  
  945. Table       dc.w  398
  946.             dc.w  375
  947.             dc.w  354
  948.             dc.w  334
  949.             dc.w  316
  950.             dc.w  298
  951.             dc.w  281
  952.             dc.w  265
  953.             dc.w  251
  954.             dc.w  236
  955.             dc.w  223
  956.             dc.w  211
  957. ORIGINAL_PITCH  dc.w  199   ; rootnote's pitch
  958.             dc.w  187
  959.             dc.w  177
  960.             dc.w  167
  961.             dc.w  157
  962.             dc.w  148
  963.             dc.w  141
  964.             dc.w  133
  965.  ; Since the minimum Amiga period = 127, the following
  966.  ; are actually out of range.
  967.             dc.w  125
  968.             dc.w  118
  969.             dc.w  112
  970.             dc.w  105
  971.             dc.w  99
  972.  
  973.   lea     ORIGINAL_PITCH,a0
  974.   move.b  MidiNoteNumber,d0  ;the received note number
  975.   sub.b   RootNote,d0        ;subtract the wave's root note
  976.   ext.w   d0
  977.   ext.l   d0                 ;make it a signed LONG
  978.   add.l   d0,d0              ;x 2 in order to fetch a WORD
  979.   adda.l  d0,a0
  980.   move.w  (a0),d0            ;the Amiga Period (WORD)
  981.  
  982.   Note that these examples don't check to see if the transpose amount is
  983. beyond the number of entries in the transpose table. Nor do they check if
  984. the periods in the table are out of range of the Amiga hardware.
  985.  
  986.  
  987.     ===================== MAKING THE VELOCITY TABLE ======================
  988.  
  989.   The 16 entries in the velocity table should be within the oneShot portion of
  990. the sample (ie not in the looping portion). THe first offset, VelTable[0]
  991. should be set to zero (in order to play back from the beginning of the data).
  992. The subsequent values should be increasing numbers. If you are using a graphic
  993. editor, try choosing offsets that will keep you within the initial attack
  994. portion of the wave. In practice, these values will be relatively close
  995. together within the wave. Always set the offsets so that when they are added
  996. to the sample start point, the resulting address points to a sample value of
  997. zero (a zero crossing point). This will eliminate pops and clicks at the
  998. beginning of the playback.
  999.  
  1000.   In addition, the start of the wave should be on a sample with a value of
  1001. zero. The last sample of the oneShot portion and the first sample of the
  1002. looping portion should be approximately equal, (or zero points). The same is
  1003. true of the first and last samples of the looping portion. Finally, try to
  1004. keep the slopes of the end of the oneShot, the beginning of the looping, and
  1005. the end of the looping section, approximately equal. All this will eliminate
  1006. noise on the audio output and provide "seamless" looping.
  1007.  
  1008.  
  1009.   ======================== THE INSTRUMENT TYPE ==========================
  1010.  
  1011.   Many SMUS players search for certain instruments by name. Not only is this
  1012. slow (comparing strings), but if the exact name can't be found, then it is
  1013. very difficult and time-consuming to search for a suitable replacement. For
  1014. this reason, many SMUS players resort to "default" instruments even if these
  1015. are nothing like the desired instruments. The InsType byte in each
  1016. waveHeader is meant to be a numeric code which will tell an SMUS player
  1017. exactly what the instrument is. In this way, the SMUS player can search for
  1018. the correct "type" of instrument if it can't find the desired name. The type
  1019. byte is divided into 2 nibbles (4 bits for you C programmers) with the low
  1020. 4 bits representing the instrument "family" as follows:
  1021.  
  1022.  1 = STRING, 2 = WOODWIND, 3 = KEYBOARD, 4 = GUITAR, 5 = VOICE, 6 = DRUM1,
  1023.  7 = DRUM2,  8 = PERCUSSION1, 9 = BRASS1, A = BRASS2, B = CYMBAL, C = EFFECT1,
  1024.  D = EFFECT2, E = SYNTH, F is undefined at this time
  1025.  
  1026.  Now, the high nibble describes the particular type within that family.
  1027.  
  1028.  For the STRING family, the high nibble is as follows:
  1029.  
  1030.  1 = VIOLIN BOW, 2 = VIOLIN PLUCK, 3 = VIOLIN GLISSANDO, 4 = VIOLIN TREMULO,
  1031.  5 = VIOLA BOW, 6 = VIOLA PLUCK, 7 = VIOLA GLIS, 8 = VIOLA TREM, 9 = CELLO
  1032.  BOW, A = CELLO PLUCK, B = CELLO GLIS, C = CELLO TREM, D = BASS BOW, E =
  1033.  BASS PLUCK (jazz bass), F = BASS TREM
  1034.  
  1035.  For the BRASS1 family, the high nibble is as follows:
  1036.  
  1037.  1 = BARITONE SAX, 2 = BARI GROWL, 3 = TENOR SAX, 4 = TENOR GROWL, 5 = ALTO
  1038.  SAX, 6 = ALTO GROWL, 7 = SOPRANO SAX, 8 = SOPRANO GROWL, 9 = TRUMPET, A =
  1039.  MUTED TRUMPET, B = TRUMPET DROP, C = TROMBONE, D = TROMBONE SLIDE, E =
  1040.  TROMBONE MUTE
  1041.  
  1042.  For the BRASS2 family, the high nibble is as follows:
  1043.  
  1044.  1 = FRENCH HORN, 2 = TUBA, 3 = FLUGAL HORN, 4 = ENGLISH HORN
  1045.  
  1046.  For the WOODWIND family, the high nibble is as follows:
  1047.  
  1048.  1 = CLARINET, 2 = FLUTE, 3 = PAN FLUTE, 4 = OBOE, 5 = PICCOLO, 6 = RECORDER,
  1049.  7 = BASSOON, 8 = BASS CLARINET, 9 = HARMONICA
  1050.  
  1051.  For the KEYBOARD family, the high nibble is as follows:
  1052.  
  1053.  1 = GRAND PIANO, 2 = ELEC. PIANO, 3 = HONKYTONK PIANO, 4 = TOY PIANO, 5 =
  1054.  HARPSICHORD, 6 = CLAVINET, 7 = PIPE ORGAN, 8 = HAMMOND B-3, 9 = FARFISA
  1055.  ORGAN, A = HARP
  1056.  
  1057.  For the DRUM1 family, the high nibble is as follows:
  1058.  
  1059.  1 = KICK, 2 = SNARE, 3 = TOM, 4 = TIMBALES, 5 = CONGA HIT, 6 = CONGA SLAP,
  1060.  7 = BRUSH SNARE, 8 = ELEC SNARE, 9 = ELEC KICK, A = ELEC TOM, B = RIMSHOT,
  1061.  C = CROSS STICK, D = BONGO, E = STEEL DRUM, F = DOUBLE TOM
  1062.  
  1063.  For the DRUM2 family, the high nibble is as follows:
  1064.  
  1065.  1 = TIMPANI, 2 = TIMPANI ROLL, 3 = LOG DRUM
  1066.  
  1067.  For the PERCUSSION1 family, the high nibble is as follows:
  1068.  
  1069.  1 = BLOCK, 2 = COWBELL, 3 = TRIANGLE, 4 = TAMBOURINE, 5 = WHISTLE, 6 =
  1070.  MARACAS, 7 = BELL, 8 = VIBES, 9 = MARIMBA, A = XYLOPHONE, B = TUBULAR BELLS,
  1071.  C = GLOCKENSPEIL
  1072.  
  1073.  For the CYMBAL family, the high nibble is as follows:
  1074.  
  1075.  1 = CLOSED HIHAT, 2 = OPEN HIHAT, 3 = STEP HIHAT, 4 = RIDE, 5 = BELL CYMBAL,
  1076.  6 = CRASH, 7 = CHOKE CRASH, 8 = GONG, 9 = BELL TREE, A = CYMBAL ROLL
  1077.  
  1078.  For the GUITAR family, the high nibble is as follows:
  1079.  
  1080.  1 = ELECTRIC, 2 = MUTED ELECTRIC, 3 = DISTORTED, 4 = ACOUSTIC, 5 = 12-STRING,
  1081.  6 = NYLON STRING, 7 = POWER CHORD, 8 = HARMONICS, 9 = CHORD STRUM, A = BANJO,
  1082.  B = ELEC. BASS, C = SLAPPED BASS, D = POPPED BASS, E = SITAR, F = MANDOLIN
  1083.  (Note that an acoustic picked bass is found in the STRINGS - Bass Pluck)
  1084.  
  1085.  For the VOICE family, the high nibble is as follows:
  1086.  
  1087.  1 = MALE AHH, 2 = FEMALE AHH, 3 = MALE OOO, 4 = FEMALE OOO, 5 = FEMALE
  1088.  BREATHY, 6 = LAUGH, 7 = WHISTLE
  1089.  
  1090.  For the EFFECTS1 family, the high nibble is as follows:
  1091.  
  1092.  1 = EXPLOSION, 2 = GUNSHOT, 3 = CREAKING DOOR OPEN, 4 = DOOR SLAM, 5 = DOOR
  1093.  CLOSE, 6 = SPACEGUN, 7 = JET ENGINE, 8 = PROPELLER, 9 = HELOCOPTER, A =
  1094.  BROKEN GLASS, B = THUNDER, C = RAIN, D = BIRDS, E = JUNGLE NOISES, F =
  1095.  FOOTSTEP
  1096.  
  1097.  For the EFFECTS2 family, the high nibble is as follows:
  1098.  
  1099.  1 = MACHINE GUN, 2 = TELEPHONE, 3 = DOG BARK, 4 = DOG GROWL, 5 = BOAT
  1100.  WHISTLE, 6 = OCEAN, 7 = WIND, 8 = CROWD BOOS, 9 = APPLAUSE, A = ROARING
  1101.  CROWDS, B = SCREAM, C = SWORD CLASH, D = AVALANCE, E = BOUNCING BALL,
  1102.  F = BALL AGAINST BAT OR CLUB
  1103.  
  1104.  For the SYNTH family, the high nibble is as follows:
  1105.  
  1106.  1 = STRINGS, 2 = SQUARE, 3 = SAWTOOTH, 4 = TRIANGLE, 5 = SINE, 6 = NOISE
  1107.  
  1108.   So, for example if a wave's type byte was 0x26, this would be a SNARE DRUM.
  1109. If a wave's type byte is 0, then this means "UNKNOWN" instrument.
  1110.  
  1111.  
  1112.   ===================== THE ORDER OF THE CHUNKS =========================
  1113.  
  1114.  The SAMP header obviously must be first in the file, followed by the MHDR
  1115. chunk. After this, the ANNO, (c), AUTH and NAME chunks may follow in any
  1116. order, though none of these need appear in the file at all. The BODY chunk
  1117. must be last.
  1118.  
  1119.  
  1120.         ================= FILENAME CONVENTIONS =================
  1121.  
  1122.    For when it becomes necessary to split a SAMP file between floppies using
  1123. the Continuation feature, the filenames should be related. The method is the
  1124. following:
  1125.  
  1126.    The "root" file has the name that the user chose to save under. Subsequent
  1127. files have an ascii number appended to the name to indicate what sublevel the
  1128. file is in. In this way, a program can reload the files in the proper order.
  1129.  
  1130.    For example, if a user saved a file called "Gurgle", the first continuation
  1131. file should be named "Gurgle1", etc.
  1132.  
  1133.  
  1134.   ============ WHY DOES ANYONE NEED SUCH A COMPLICATED FILE? ==============
  1135.                  (or "What's wrong with 8SVX anyway?")
  1136.  
  1137.   In a nutshell, 8SVX is not adequate for professional music sampling. First
  1138. of all, it is nearly impossible to use multi-sampling (utilizing several,
  1139. different samples of any instrument throughout its musical range). This very
  1140. reason alone makes it impossible to realistically reproduce a musical in-
  1141. strument, as none in existance (aside from an electronic organ) uses inter-
  1142. polations of a single wave to create its musical note range.
  1143.   Also, stretching a sample out over an entire octave range does grotesque
  1144. (and VERY unmusical) things to such elements as the overtone structure,
  1145. wind/percussive noises, the instrument's amplitude envelope, etc. The 8SVX
  1146. format is designed to stretch the playback in exactly this manner.
  1147.   8SVX ignores MIDI which is the de facto standard of musical data transmission.
  1148.   8SVX does not allow storing data for features that are commonplace to pro-
  1149. fessional music samplers. Such features are: velocity sample start, separate
  1150. filter and envelopes for each sample, separate sampling rates, and various
  1151. playback modes like stereo sampling and panning.
  1152.   SAMP attempts to remedy all of these problems with a format that can be
  1153. used by a program that simulates these professional features in software. The
  1154. format was inspired by the capabilities of the following musical products:
  1155.  
  1156.   EMU's                 EMAX, EMULATOR
  1157.   SEQUENTIAL CIRCUIT's  PROPHET 2000, STUDIO 440
  1158.   ENSONIQ's             MIRAGE
  1159.   CASIO's               FZ-1
  1160.   OBERHEIM's            DPX
  1161.   YAMAHA                TX series
  1162.  
  1163.    So why does the Amiga need the SAMP format? Because professional musician's
  1164. are buying computers. With the firm establishment of MIDI, musician's are
  1165. buying and using a variety of sequencers, patch editors, and scoring programs.
  1166. It is now common knowledge amoung professional musicians that the Amiga
  1167. lags far behind IBM clones, Macintosh, and Atari ST computers in both music
  1168. software and hardware support. Both Commodore and the current crop of short-
  1169. sighted 3rd party Amiga developers are pigeon-holing the Amiga as "a video
  1170. computer". It is important for music software to exploit whatever capabili-
  1171. ties the Amiga offers before the paint and animation programs, genlocks,
  1172. frame-grabbers, and video breadboxes are the only applications selling
  1173. for the Amiga. Hopefully, this format, with the SAMP disk I/O library will
  1174. make it possible for Amiga software to attain the level of professionalism
  1175. that the other machines now boast, and the Amiga lacks.
  1176.