home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 1: Collection A / 17Bit_Collection_A.iso / files / 61.dms / 61.adf / iff.text / smus < prev   
Text File  |  1986-03-21  |  47KB  |  1,143 lines

  1. "SMUS" IFF Simple Musical Score
  2.  
  3. Date:    February 5, 1986
  4. From:    Jerry Morrison, Electronic Arts
  5. Status:    Adopted
  6.  
  7. 1. Introduction
  8.  
  9. This is a reference manual for the data interchange format "SMUS", 
  10. which stands for Simple MUsical Score. "EA IFF 85" is Electronic Arts' 
  11. standard for interchange format files. A FORM (or "data section") 
  12. such as FORM SMUS can be an IFF file or a part of one. [See "EA IFF 
  13. 85" Electronic Arts Interchange File Format.]
  14.  
  15. SMUS is a practical data format for uses like moving limited scores 
  16. between programs and storing theme songs for game programs. The format 
  17. should be geared for easy read-in and playback. So FORM SMUS uses 
  18. the compact time encoding of Common Music Notation (half notes, dotted 
  19. quarter rests, etc.). The SMUS format should also be structurally 
  20. simple. So it has no provisions for fancy notational information needed 
  21. by graphical score editors or the more general timing (overlapping 
  22. notes, etc.) and continuous data (pitch bends, etc.) needed by 
  23. performance-oriented MIDI recorders and sequencers.
  24.  
  25. A SMUS score can say which "instruments" are supposed play which notes. 
  26. But the score is independent of whatever output device and driver 
  27. software is used to perform the notes. The score can contain device- 
  28. and driver-dependent instrument data, but this is just a cache. As 
  29. long as a SMUS file stays in one environment, the embedded instrument 
  30. data is very convenient. When you move a SMUS file between programs 
  31. or hardware configurations, the contents of this cache usually become 
  32. useless.
  33.  
  34. Like all IFF formats, SMUS is a filed or "archive" format. It is completely 
  35. independent of score representations in working memory, editing operations, 
  36. user interface, display graphics, computation hardware, and sound 
  37. hardware. Like all IFF formats, SMUS is extensible.
  38.  
  39. SMUS is not an end-all musical score format. Other formats may be 
  40. more appropriate for certain uses. (We'd like to design an general-use 
  41. IFF score format "GSCR". FORM GSCR would encode fancy notational data 
  42. and performance data. There would be a SMUS to/from GSCR converter.)
  43.  
  44. Section 2 gives important background information. Section 3 details 
  45. the SMUS components by defining the required property score header 
  46. "SHDR", the optional text properties name "NAME", copyright "(c) ", 
  47. and author "AUTH", optional text annotation "ANNO", the optional instrument 
  48. specifier "INS1", and the track data chunk "TRAK". Section 4 defines 
  49. some chunks for particular programs to store private information. 
  50. These are "standard" chunks; specialized chunks for future needs can 
  51. be added later. Appendix A is a quick-reference summary. Appendix 
  52. B is an example box diagram. Appendix C names the committee responsible 
  53. for this standard.
  54.  
  55. Update: This standard has been revised since the draft versions. The 
  56. "INST" chunk type was revised to form the "INS1" chunk type. Also, 
  57. several SEvent types and a few text chunk types have been added.
  58.  
  59. Note: This is a MacWrite[tm] 4.5 document. If you strip it down to a 
  60. text file, you'll lose pictures, significant formatting information 
  61. like superscripts, and characters like ")". Don't do it.  
  62.  
  63.  
  64.   ----------------------------------------------------------------
  65.   |(Sorry, EA. We had to strip it down for ease of distribution, |
  66.   |  but we did convert pictures to text-form and where we could |
  67.   |  not do that, we provided ILBM illustrations that people     |
  68.   |  could actually show using the standard "showilbm" program)  |
  69.   ----------------------------------------------------------------
  70.  
  71.  
  72. References:
  73.  
  74. "EA IFF 85" Standard for Interchange Format Files describes the underlying 
  75. conventions for all IFF files.
  76.  
  77. "8SVX" IFF 8-Bit Sampled Voice documents a data format for sampled 
  78. instruments.
  79.  
  80. Electronic Arts[tm] is a trademark of Electronic Arts.
  81.  
  82. MIDI: Musical Instrument Digital Interface Specification 1.0, International 
  83. MIDI Association, 1983.
  84.  
  85. MacWrite[tm] is a trademark of Apple Computer, Inc.
  86.  
  87. SSSP: See various articles on Structured Sound Synthesis Project in 
  88. Foundations of Computer Music.
  89.  
  90.  
  91.  
  92.  
  93. 2. Background
  94.  
  95. Here's some background information on score representation in general 
  96. and design choices for SMUS.
  97.  
  98. First, we'll borrow some terminology from the Structured Sound Synthesis 
  99. Project. [See the SSSP reference.] A "musical note" is one kind of 
  100. scheduled event. It's properties include an event duration, an event 
  101. delay, and a timbre object. Theevent duration tells the scheduler 
  102. how long the note should last. The event delay tells how long after 
  103. starting this note to wait before starting the next event. The timbre 
  104. object selects sound driver data for the note; an "instrument" or 
  105. "timbre". A "rest" is a sort of a null event. Its only property is 
  106. an event delay.
  107.  
  108. Classical Event Durations
  109.  
  110. SMUS is geared for "classical" scores, not free-form performances. 
  111. So its event durations are classical (whole note, dotted quarter rest, 
  112. etc.). It can tie notes together to build a "note event" with an unusual 
  113. event duration.
  114.  
  115. The set of useful classical durations is very small. So SMUS needs 
  116. only a handful of bits to encode an event duration. This is very compact. 
  117. It's also very easy to display in Common Music Notation (CMN).
  118.  
  119. Tracks
  120.  
  121. The events in a SMUS score are grouped into parallel "tracks". Each 
  122. track is a linear stream of events.
  123.  
  124. Why use tracks? Tracks serve 4 functions:
  125.  
  126. 1.    Tracks make it possible to encode event delays very compactly. 
  127. A "classical" score has chorded notes and sequential notes; no overlapping 
  128. notes. That is, each event begins either simultaneous with or immediately 
  129. following the previous event in that track. So each event delay is 
  130. either 0 or the same as the event's duration. This binary distinction 
  131. requires only one bit of storage.
  132.  
  133. 2.    Tracks represent the "voice tracks" in Common Music Notation. 
  134. CMN organizes a score in parallel staves, with one or two "voice tracks" 
  135. per staff. So one or two SMUS tracks represents a CMN staff.
  136.  
  137. 3.    Tracks are a good match to available sound hardware. We can 
  138. use "instrument settings" in a track to store the timbre assignments 
  139. for that track's notes. The instrument setting may change over the 
  140. track.
  141.  
  142.     Furthermore, tracks can help to allocate notes among available 
  143. output channels or performance devices or tape recorder "tracks". 
  144. Tracks can also help to adapt polyphonic data to monophonic output 
  145. channels.
  146.  
  147. 4.    Tracks are a good match to simple sound software. Each track 
  148. is a place to hold state settings like "dynamic mark pp ", "time signature 
  149. 3/4", "mute this track", etc., just as it's a context for instrument 
  150. settings. This is a lot like a text stream with running "font" and 
  151. "face" properties (attributes). Running state is usually more compact 
  152. than, say, storing an instrument setting in every note event. It's 
  153. also a useful way to organize "attributes" of notes. With "running 
  154. track state" we can define new note attributes in an upward- and 
  155. backward-compatible way.
  156.  
  157.     Running track state can be expanded (run decoded) while loading 
  158. a track into memory or while playing the track. The runtime track 
  159. state must be reinitialized every time the score is played.
  160.  
  161. Separated vs. interleaved tracks. Multi-track data could be stored 
  162. either as separate event streams or interleaved into one stream. To 
  163. interleave the streams, each event has to carry a "track number" attribute.
  164.  
  165. If we were designing an editable score format, we might interleave 
  166. the streams so that nearby events are stored nearby. This helps when 
  167. searching the data, especially if you can't fit the entire score into 
  168. memory at once. But it takes extra storage for the track numbers and 
  169. may take extra work to manipulate the interleaved tracks.
  170.  
  171. The musical score format FORM SMUS is intended for simple loading 
  172. and playback of small scores that fit entirely in main memory. So 
  173. we chose to store its tracks separately.
  174.  
  175. There can be up to 255 tracks in a FORM SMUS. Each track is stored 
  176. as a TRAK chunk. The count of tracks (the number of TRAK chunks) is 
  177. recorded in the SHDR chunk at the beginning of the FORM SMUS. The 
  178. TRAK chunks appear in numerical order 1, 2, 3, .... This is also priority 
  179. order, most important track first. A player program that can handle 
  180. up to N parallel tracks should read the first N tracks and ignore 
  181. any others.
  182.  
  183. The different tracks in a score may have different lengths. This is 
  184. true both of storage length and of playback duration.
  185.  
  186. Instrument Registers
  187.  
  188. Instrument reference. In SSSP, each note event points to a "timbre 
  189. object" which supplies the "instrument" (the sound driver data) for 
  190. that note. FORM SMUS stores these pointers as a "current instrument 
  191. setting" for each track. It's just a run encoded version of the same 
  192. information. SSSP uses a symbol table to hold all the pointers to 
  193. "timbre object". SMUS uses INS1 chunks for the same purpose. They 
  194. name the score's instruments.
  195.  
  196. The actual instrument data to use depends on the playback environment, 
  197. but we want the score to be independent of environment. Different 
  198. playback environments have different audio output hardware and different 
  199. sound driver software. And there are channel allocation issues like 
  200. how many output channels there are, which ones are polyphonic, and 
  201. which I/O ports they're connected to. If you use MIDI to control the 
  202. instruments, you get into issues of what kind of device is listening 
  203. to each MIDI channel and what each of its preset sounds like. If you 
  204. use computer-based instruments, you need driver-specific data like 
  205. waveform tables and oscillator parameters.
  206.  
  207. We just want to put some orchestration in the score. If the score 
  208. wants a "piano", we let the playback program to find a "piano".
  209.  
  210. Instrument reference by name. A reference from a SMUS score to actual 
  211. instrument data is normally by name. The score simply names the instrument, 
  212. for instance "tubular bells". It's up to the player program to find 
  213. suitable instrument data for its output devices. (More on locating 
  214. instruments below.)
  215.  
  216. Instrument reference by MIDI channel and preset. A SMUS score can 
  217. also ask for a specific MIDI channel number and preset number. MIDI 
  218. programs may honor these specific requests. But these channel allocations 
  219. can become obsolete or the score may be played without MIDI hardware. 
  220. In such cases, the player program should fall back to instrument reference 
  221. by name.
  222.  
  223. Instrument reference via instrument register. Each reference from 
  224. a SMUS track to an instrument is via an "instrument register". Each 
  225. track selects an instrument register which in turn points to the specific 
  226. instrument data.
  227.  
  228. Each score has an array of instrument registers. Each track has a 
  229. "current instrument setting", which is simply an index number into 
  230. this array. This is like setting a raster image's pixel to a specific 
  231. color number (a reference to a color value through a "color register") 
  232. or setting a text character to a specific font number (a reference 
  233. to a font through a "font register"). This is diagrammed below.
  234.  
  235.  
  236.  Track 1  |Set Inst 2| Note | Note | Set Inst 1 | Note | Note | Note |... 
  237.         |              |
  238.   +-------------+              |
  239.   |  +------------------------------------+
  240.   |  |           +--------------------------------------------------------+
  241.   |  +-------->|"piano"  ---------------> (internal piano data)         |
  242.   +----------->|"guitar" ---------------> (internal guitar data)    |
  243.            |"Spanish guitar" -------> (internal Spanish guitar data)|
  244.      +-------->|"bass drum" ------------> (internal bass drum data)    |
  245.      |           +--------------------------------------------------------+
  246.      |
  247.      +---------+
  248.            |
  249.  Track 2  |Set Inst 4| Note | Note | Note | Note | Note | Note | Note |... 
  250.  
  251.  
  252.  
  253. Locating instrument data by name. "INS1" chunks in a SMUS score name 
  254. the instruments to use for that score. The player program uses these 
  255. names to locate instrument data.
  256.  
  257. To locate instrument data, the player performs these steps:
  258.  
  259. For each instrument register, check for a suitable instrument with 
  260. the right name.  "Suitable" means usable with an available output 
  261. device and driver.  {Use case independent name comparisons.}
  262.  
  263. 1.    Initialize the instrument register to point to a built-in default 
  264.     instrument.  {Every player program must have default instruments. 
  265.     Simple programs stop here. For fancier programs, the default 
  266.     instruments are a backstop in case the search fails.}
  267.  
  268. 2.    Check any instrument FORMs embedded in the FORM SMUS. (This 
  269.     is an "instrument cache".)
  270.  
  271. 3.    Else check the default instruments.
  272.  
  273. 4.    Else search the local "instrument library". (The library might 
  274.     simply be a disk directory.)
  275.  
  276. 5.    If all else fails, display the desired instrument name and 
  277.     ask the user to pick an available one.
  278.  
  279. This algorithm can be implemented to varying degrees of fanciness. 
  280. It's ok to stop searching after step 1, 2, 3, or 4. If exact instrument 
  281. name matches fail, it's ok to try approximate matches. E.g. search 
  282. for any kind of "guitar" if you can't find a "Spanish guitar". In 
  283. any case, a player only has to search for instruments while loading 
  284. a score.
  285.  
  286. When the embedded instruments are suitable, they save the program 
  287. from asking the user to insert the "right" disk in a drive and searching 
  288. that disk for the "right" instrument. But it's just a cache. In practice, 
  289. we rarely move scores between environments so the cache often works. 
  290. When the score is moved, embedded instruments must be discarded (a 
  291. cache miss) and other instrument data used.
  292.  
  293. Be careful to distinguish an instrument's name from its filenameQthe 
  294. contents name vs. container name. A musical instrument FORM should 
  295. contain a NAME chunk that says what instrument it really is. Its filename, 
  296. on the other hand, is a handle used to locate the FORM. Filenames 
  297. are affected by external factors like drives, directories, and filename 
  298. character and length limits. Instrument names are not.
  299.  
  300. Issue: Consider instrument naming conventions for consistency. Consider 
  301. a naming convention that aids approximate matches. E.g. we could accept 
  302. "guitar, bass1" if we didn't find "guitar, bass". Failing that, we 
  303. could accept "guitar" or any name starting with "guitar".
  304.  
  305. Set instrument events. If the player implements the set-instrument 
  306. score event, each track can change instrument numbers while playing. 
  307. That is, it can switch between the loaded instruments.
  308.  
  309. Initial instrument settings. Each time a score is played, every tracks' 
  310. running state information must be initialized. Specifically, each 
  311. track's instrument number should be initialized to its track number. 
  312. Track 1 to instrument 1, etc. It's as if each track began with a 
  313. set-instrument event.
  314.  
  315. In this way, programs that don't implement the set-instrument event 
  316. still assign an instrument to each track. The INS1 chunks imply these 
  317. initial instrument settings.
  318.  
  319. MIDI Instruments
  320.  
  321. As mentioned above, A SMUS score can also ask for MIDI instruments. 
  322. This is done by putting the MIDI channel and preset numbers in an 
  323. INS1 chunk with the instrument name. Some programs will honor these 
  324. requests while others will just find instruments by name.
  325.  
  326. MIDI Recorder and sequencer programs may simply transcribe the MIDI 
  327. channel and preset commands in a recording session. For this purpose, 
  328. set-MIDI-channel and set-MIDI-preset events can be embedded in a SMUS 
  329. score's tracks. Most programs should ignore these events. An editor 
  330. program that wants to exchange scores with such programs should recognize 
  331. these events. It should let the user change them to the more general 
  332. set-instrument events.
  333.  
  334.  
  335.  
  336. 3. Standard Data and Property Chunks
  337.  
  338. A FORM SMUS contains a required property "SHDR" followed by any number 
  339. of parallel "track" data chunks "TRAK". Optional property chunks such 
  340. as "NAME", copyright "(c) ", and instrument reference "INS1" may also 
  341. appear. Any of the properties may be shared over a LIST of FORMs SMUS 
  342. by putting them in a PROP SMUS. [See the IFF reference.]
  343.  
  344. Required Property SHDR
  345.  
  346. The required property "SHDR" holds an SScoreHeader as defined in these 
  347. C declarations and following documentation. An SHDR specifies global 
  348. information for the score. It must appear before the TRAKs in a FORM 
  349. SMUS.
  350.  
  351. #define ID_SMUS MakeID('S', 'M', 'U', 'S')
  352. #define ID_SHDR MakeID('S', 'H', 'D', 'R')
  353.  
  354. typedef struct {
  355.     UWORD tempo;    /* tempo, 128ths quarter note/minute    */
  356.     UBYTE volume;    /* overall playback volume 0 through 127    */
  357.     UBYTE ctTrack;    /* count of tracks in the score    */
  358.     } SScoreHeader;
  359.  
  360. [Implementation details. In the C struct definitions in this memo, 
  361. fields are filed in the order shown. A UBYTE field is packed into 
  362. an 8-bit byte. Programs should set all "pad" fields to 0. MakeID is 
  363. a C macro defined in the main IFF document and in the source file 
  364. IFF.h.]
  365.  
  366. The field tempo gives the nominal tempo for all tracks in the score. 
  367. It is expressed in 128ths of a quarter note per minute, i.e. 1 represents 
  368. 1 quarter note per 128 minutes while 12800 represents 100 quarter 
  369. notes per minute. You may think of this as a fixed point fraction 
  370. with a 9-bit integer part and a 7-bit fractional part (to the right 
  371. of the point). A course-tempoed program may simply shift tempo right 
  372. by 7 bits to get a whole number of quarter notes per minute. The tempo 
  373. field can store tempi in the range 0 up to 512. The playback program 
  374. may adjust this tempo, perhaps under user control.
  375.  
  376. Actually, this global tempo could actually be just an initial tempo 
  377. if there are any "set tempo" SEvents inside the score (see TRAK, below). 
  378. Or the global tempo could be scaled by "scale tempo" SEvents inside 
  379. the score. These are potential extensions that can safely be ignored 
  380. by current programs. [See More SEvents To Be Defined, below.]
  381.  
  382. The field volume gives an overall nominal playback volume for all 
  383. tracks in the score. The range of volume values 0 through 127 is like 
  384. a MIDI key velocity value. The playback program may adjust this volume, 
  385. perhaps under direction of a user "volume control".
  386.  
  387. Actually, this global volume level could be scaled by dynamic-mark 
  388. SEvents inside the score (see TRAK, below).
  389.  
  390. The field ctTrack holds the count of tracks, i.e. the number of TRAK 
  391. chunks in the FORM SMUS (see below). This information helps the reader 
  392. prepare for the following data.
  393.  
  394. A playback program will typically load the score and call a driver 
  395. routine PlayScore(tracks, tempo, volume), supplying the tempo and 
  396. volume from the SHDR chunk.
  397.  
  398. Optional Text Chunks NAME, (c), AUTH, ANNO
  399.  
  400. Several text chunks may be included in a FORM SMUS to keep ancillary 
  401. information.
  402.  
  403. The optional property "NAME" names the musical score, for instance 
  404. "Fugue in C".
  405.  
  406. The optional property "(c)J" holds a copyright notice for the score. 
  407. The chunk ID "(c)J" serves the function of the copyright characters 
  408. ")J". E.g. a "(c)J" chunk containing "1986 Electronic Arts" means 
  409. ") 1986 Electronic Arts".
  410.  
  411. The optional property "AUTH" holds the name of the score's author.
  412.  
  413. The chunk types "NAME", "(c) ", and "AUTH" are property chunks. Putting 
  414. more than one NAME (or other) property in a FORM is redundant. Just 
  415. the last NAME counts. A property should be shorter than 256 characters. 
  416. Properties can appear in a PROP SMUS to share them over a LIST of 
  417. FORMs SMUS.
  418.  
  419. The optional data chunk "ANNO" holds any text annotations typed in 
  420. by the author.
  421.  
  422. An ANNO chunk is not a property chunk, so you can put more than one 
  423. in a FORM SMUS. You can make ANNO chunks any length up to 231 - 1 
  424. characters, but 32767 is a practical limit. Since they're not properties, 
  425. ANNO chunks don't belong in a PROP SMUS. That means they can't be 
  426. shared over a LIST of FORMs SMUS.
  427.  
  428. Syntactically, each of these chunks contains an array of 8-bit ASCII 
  429. characters in the range R S (SP, hex 20) through R~S (tilde, hex 7F), 
  430. just like a standard "TEXT" chunk. [See "Strings, String Chunks, and 
  431. String Properties" in "EA IFF 85" Electronic Arts Interchange File 
  432. Format.] The chunk's ckSize field holds the count of characters.
  433.  
  434. #define ID_NAME MakeID('N', 'A', 'M', 'E')
  435. /* NAME chunk contains a CHAR[], the musical score's name.    */
  436.  
  437. #define ID_Copyright MakeID('(', 'c', ')', ' ')
  438. /* "(c) " chunk contains a CHAR[], the FORM's copyright notice.    */
  439.  
  440. #define ID_AUTH MakeID('A', 'U', 'T', 'H')
  441. /* AUTH chunk contains a CHAR[], the name of the score's author.    */
  442.  
  443. #define ID_ANNO MakeID('A', 'N', 'N', 'O')
  444. /* ANNO chunk contains a CHAR[], author's text annotations.    */
  445.  
  446. Remember to store a 0 pad byte after any odd-length chunk.
  447.  
  448. Optional Property INS1
  449.  
  450. The "INS1" chunks in a FORM SMUS identify the instruments to use for 
  451. this score. A program can ignore INS1 chunks and stick with its built-in 
  452. default instrument assignments. Or it can use them to locate instrument 
  453. data. [See "Instrument Registers" in section 2, above.]
  454.  
  455. #define ID_INS1 MakeID('I', 'N', 'S', '1')
  456.  
  457. /* Values for the RefInstrument field "type".    */
  458. #define INS1_Name  0    /* just use the name; ignore data1, data2    */
  459. #define INS1_MIDI  1    /* <<data1, data2> = MIDI <<channel, preset>    */
  460.  
  461. typedef struct {
  462.     UBYTE register;    /* set this instrument register number    */
  463.     UBYTE type;    /* instrument reference type    */
  464.     UBYTE data1, data2;    /* depends on the "type" field    */
  465.     CHAR  name[];    /* instrument name    */
  466.     } RefInstrument;
  467.  
  468. An INS1 chunk names the instrument for instrument register number 
  469. register. The register field can range from 0 through 255. In practice, 
  470. most scores will need only a few instrument registers.
  471.  
  472. The name field gives a text name for the instrument. The string length 
  473. can be determined from the ckSize of the INS1 chunk. The string is 
  474. simply an array of 8-bit ASCII characters in the range R S (SP, hex 
  475. 20) through R~S (tilde, hex 7F).
  476.  
  477. Besides the instrument name, an INS1 chunk has two data numbers to 
  478. help locate an instrument. The use of these data numbers is controlled 
  479. by the type field. A value type = INS1_Name means just find an instrument 
  480. by name. In this case, data1 and data2 should just be set to 0. A 
  481. value type = INS1_MIDI means look for an instrument on MIDI channel 
  482. # data1, preset # data2. Programs and computers without MIDI outputs 
  483. will just ignore the MIDI data. They'll always look for the named 
  484. instrument. Other values of the type field are reserved for future 
  485. standardization.
  486.  
  487. See section 2, above, for the algorithm for locating instrument data 
  488. by name.
  489.  
  490. Obsolete Property INST
  491.  
  492. The chunk type "INST" is obsolete in SMUS. It was revised to form 
  493. the "INS1" chunk.
  494.  
  495. Data Chunk TRAK
  496.  
  497. The main contents of a score is stored in one or more TRAK chunks 
  498. representing parallel "tracks". One TRAK chunk per track.
  499.  
  500. The contents of a TRAK chunk is an array of 16-bit "events" such as 
  501. "note", "rest", and "set instrument". Events are really commands to 
  502. a simple scheduler, stored in time order. The tracks can be polyphonic, 
  503. that is, they can contain chorded "note" events.
  504.  
  505. Each event is stored as an "SEvent" record. ("SEvent" means "simple 
  506. musical event".) Each SEvent has an 8-bit type field called an "sID" 
  507. and 8 bits of type-dependent data. This is like a machine language 
  508. instruction with an 8-bit opcode and an 8-bit operand.
  509.  
  510. This format is extensible since new event types can be defined in 
  511. the future. The "note" and "rest" events are the only ones that every 
  512. program must understand. We will carefully design any new event types 
  513. so that programs can safely skip over unrecognized events in a score.
  514.  
  515. Caution: SID codes must be allocated by a central clearinghouse to 
  516. avoid conflicts.
  517.  
  518. Here are the C type definitions for TRAK and SEvent and the currently 
  519. defined sID values. Afterward are details on each SEvent.
  520.  
  521. #define ID_TRAK MakeID('T', 'R', 'A', 'K')
  522.  
  523. /* TRAK chunk contains an SEvent[].    */
  524.  
  525. /* SEvent: Simple musical event.    */
  526. typedef struct {
  527.     UBYTE sID;    /* SEvent type code    */
  528.     UBYTE data;    /* sID-dependent data    */
  529.     } SEvent;
  530.  
  531. /* SEvent type codes "sID".        */
  532. #define SID_FirstNote     0
  533. #define SID_LastNote    127    /* sIDs in the range SID_FirstNote through
  534.                   * SID_LastNote (sign bit = 0) are notes. The
  535.                   * sID is the MIDI tone number (pitch).    */
  536. #define SID_Rest        128    /* a rest (same data format as a note).    */
  537.  
  538. #define SID_Instrument  129    /* set instrument number for this 
  539. track.    */
  540. #define SID_TimeSig     130    /* set time signature for this track.    */
  541. #define SID_KeySig      131    /* set key signature for this track.    */
  542. #define SID_Dynamic     132    /* set volume for this track.    */
  543. #define SID_MIDI_Chnl   133    /* set MIDI channel number (sequencers)    */
  544. #define SID_MIDI_Preset 134    /* set MIDI preset number (sequencers)    */
  545.  
  546. /* SID values 144 through 159: reserved for Instant Music SEvents.    */
  547.  
  548. /* Remaining sID values up through 254: reserved for future
  549.  * standardization.        */
  550.  
  551. #define SID_Mark        255    /* sID reserved for an end-mark in RAM.    */
  552.  
  553. Note and Rest SEvents
  554.  
  555. The note and rest SEvents SID_FirstNote through SID_Rest have the 
  556. following structure overlaid onto the SEvent structure:
  557.  
  558. typedef struct {
  559.     UBYTE    tone;    /* MIDI tone number 0 to 127; 128 = rest    */
  560.     unsigned chord    :1,    /* 1 = a chorded note    */
  561.         tieOut   :1,    /* 1 = tied to the next note or chord    */
  562.         nTuplet  :2,    /* 0 = none, 1 = triplet, 2 = quintuplet,
  563.     * 3 = septuplet    */
  564.         dot      :1,    /* dotted note; multiply duration by 3/2    */
  565.         division :3;    /* basic note duration is 2-division: 0 = whole
  566.               * note, 1 = half note, 2 = quarter note, I 
  567.              * 7 = 128th note    */
  568.     } SNote;
  569.  
  570. [Implementation details. Unsigned ":n" fields are packed into n bits 
  571. in the order shown, most significant bit to least significant bit. 
  572. An SNote fits into 16 bits like any other SEvent. Warning: Some compilers 
  573. don't implement bit-packed fields properly. E.g. Lattice 68000 C pads 
  574. a group of bit fields out to a LONG, which would make SNote take 5-bytes! 
  575. In that situation, use the bit-field constants defined below.]
  576.  
  577. The SNote structure describes one "note" or "rest" in a track. The 
  578. field SNote.tone, which is overlaid with the SEvent.sID field, indicates 
  579. the MIDI tone number (pitch) in the range 0 through 127. A value of 
  580. 128 indicates a rest.
  581.  
  582. The fields nTuplet, dot, and division together give the duration of 
  583. the note or rest. The division gives the basic duration: whole note, 
  584. half note, etc. The dot indicates if the note or rest is dotted. A 
  585. dotted note is 3/2 as long as an undotted note. The value nTuplet 
  586. (0 through 3) tells if this note or rest is part of an N-tuplet of 
  587. order 1 (normal), 3, 5, or 7; an N-tuplet of order (2J*JnTupletJ+J1). 
  588. A triplet note is 2/3 as long as a normal note, while a quintuplet 
  589. is 4/5 as long and a septuplet is 6/7 as long.
  590.  
  591. Putting these three fields together, the duration of the note or rest 
  592. is 2-division * {1, 3/2} * {1, 2/3, 4/5, 6/7}
  593.  
  594. These three fields are contiguous so you can easily convert to your 
  595. local duration encoding by using the combined 6 bits as an index into 
  596. a mapping table.
  597.  
  598. The field chord indicates if the note is chorded with the following 
  599. note (which is supposed to have the same duration). A group of notes 
  600. may be chorded together by setting the chord bit of all but the last 
  601. one. (In the terminology of SSSP and GSCR, setting the chord bit to 
  602. 1 makes the "entry delay" 0.) A monophonic-track player can simply 
  603. ignore any SNote event whose chord bit is set, either by discarding 
  604. it when reading the track or by skipping it when playing the track.
  605.  
  606. Programs that create polyphonic tracks are expected to store the most 
  607. important note of each chord last, which is the note with the 0 chord 
  608. bit. This way, monophonic programs will play the most important note 
  609. of the chord. The most important note might be the chord's root note 
  610. or its melody note.
  611.  
  612. If the field tieOut is set, the note is tied to the following note 
  613. in the track if the following note has the same pitch. A group of 
  614. tied notes is played as a single note whose duration is the sum of 
  615. the component durations. Actually, the tie mechanism ties a group 
  616. of one or more chorded notes to another group of one or more chorded 
  617. notes. Every note in a tied chord should have its tieOut bit set.
  618.  
  619. Of course, the chord and tieOut fields don't apply to SID_Rest SEvents.
  620.  
  621. Programs should be robust enough to ignore an unresolved tie, i.e. 
  622. a note whose tieOut bit is set but isn't followed by a note of the 
  623. same pitch. If that's true, monophonic-track programs can simply ignore 
  624. chorded notes even in the presense of ties. That is, tied chords pose 
  625. no extra problems.
  626.  
  627. The following diagram shows some combinations of notes and chords 
  628. tied to notes and chords. The text below the staff has a column for 
  629. each SNote SEvent to show the pitch, chord bit, and tieOut bit.
  630.  
  631.  
  632.  
  633.         (figure)
  634.  
  635.  
  636.  
  637.  
  638. If you read the above track into a monophonic-track program, it'll 
  639. strip out the chorded notes and ignore unresolved ties. You'll end 
  640. up with:
  641.  
  642.  
  643.  
  644.         (figure)
  645.  
  646.  
  647.  
  648.  
  649. A rest event (sID = SID_Rest) has the same SEvent.data field as a 
  650. note. It tells the duration of the rest. The chord and tieOut fields 
  651. of rest events are ignored.
  652.  
  653. Within a TRAK chunk, note and rest events appear in time order.
  654.  
  655. Instead of the bit-packed structure SNote, it might be easier to assemble 
  656. data values by or-ing constants and to disassemble them by masking 
  657. and shifting. In that case, use the following definitions.
  658.  
  659. #define noteChord  (1<<<<7)    /* note is chorded to next note    */
  660.  
  661. #define noteTieOut (1<<<<6)    /* tied to next note/chord    */
  662.  
  663. #define noteNShift 4    /* shift count for nTuplet field    */
  664. #define noteN3     (1<<<<noteNShift)    /* note is a triplet    */
  665. #define noteN5     (2<<<<noteNShift)    /* note is a quintuplet    */
  666. #define noteN7     (3<<<<noteNShift)    /* note is a septuplet    */
  667. #define noteNMask  noteN7    /* bit mask for the nTuplet field    */
  668.  
  669. #define noteDot    (1<<<<3)    /* note is dotted    */
  670.  
  671. #define noteD1     0    /* whole note division    */
  672. #define noteD2     1    /* half note division    */
  673. #define noteD4     2    /* quarter note division    */
  674. #define noteD8     3     /* eighth note division    */
  675. #define noteD16    4     /* sixteenth note division    */
  676. #define noteD32    5     /* thirty-secondth note division    */
  677. #define noteD64    6     /* sixty-fourth note division    */
  678. #define noteD128   7     /* 1/128 note division    */
  679. #define noteDMask  noteD128    /* bit mask for the division field    */
  680.  
  681. #define noteDurMask 0x3F    /* mask for combined duration fields    */
  682.  
  683. Note: The remaining SEvent types are optional. A writer program doesn't 
  684. have to generate them. A reader program can safely ignore them.
  685.  
  686. Set Instrument SEvent
  687.  
  688. One of the running state variables of every track is an instrument 
  689. number. An instrument number is the array index of an "instrument 
  690. register", which in turn points to an instrument. (See "Instrument 
  691. Registers", in section 2.) This is like a color number in a bitmap; 
  692. a reference to a color through a "color register".
  693.  
  694. The initial setting for each track's instrument number is the track 
  695. number. Track 1 is set to instrument 1, etc. Each time the score is 
  696. played, every track's instrument number should be reset to the track 
  697. number.
  698.  
  699. The SEvent SID_Instrument changes the instrument number for a track, 
  700. that is, which instrument plays the following notes. Its SEvent.data 
  701. field is an instrument register number in the range 0 through 255. 
  702. If a program doesn't implement the SID_Instrument event, each track 
  703. is fixed to one instrument.
  704.  
  705. Set Time Signature SEvent
  706.  
  707. The SEvent SID_TimeSig sets the time signature for the track. A "time 
  708. signature" SEvent has the following structure overlaid on the SEvent 
  709. structure:
  710.  
  711. typedef struct {
  712.     UBYTE    type;    /* = SID_TimeSig    */
  713.     unsigned timeNSig :5,    /* time sig. "numerator" is timeNSig + 1 */ 
  714.     timeDSig :3;    /* time sig. "denominator" is 2timeDSig: 
  715.              * 0 = whole note, 1 = half note, 2 = quarter      
  716.              * note, I 7 = 128th note    */
  717.     } STimeSig;
  718.  
  719. [Implementation details. Unsigned ":n" fields are packed into n bits 
  720. in the order shown, most significant bit to least significant bit. 
  721. An STimeSig fits into 16 bits like any other SEvent. Warning: Some 
  722. compilers don't implement bit-packed fields properly. E.g. Lattice 
  723. C pads a group of bit fields out to a LONG, which would make an STimeSig 
  724. take 5-bytes! In that situation, use the bit-field constants defined 
  725. below.]
  726.  
  727. The field type contains the value SID_TimeSig, indicating that this 
  728. SEvent is a "time signature" event. The field timeNSig indicates the 
  729. time signature "numerator" is timeNSig + 1, that is, 1 through 32 
  730. beats per measure. The field timeDSig indicates the time signature 
  731. "denominator" is 2timeDSig, that is each "beat" is a 2-timeDSig note 
  732. (see SNote division, above). So 4/4 time is expressed as timeNSig 
  733. = 3, timeDSig = 2.
  734.  
  735. The default time signature is 4/4 time.
  736.  
  737. Beware that the time signature has no effect on the score's playback. 
  738. Tempo is uniformly expressed in quarter notes per minute, independent 
  739. of time signature. (Quarter notes per minute equals beats per minute 
  740. only if timeDSig = 2, n/4 time). Nonetheless, any program that has 
  741. time signatures should put them at the beginning of each TRAK when 
  742. creating a FORM SMUS because music editors need them.
  743.  
  744. Instead of the bit-packed structure STimeSig, it might be easier to 
  745. assemble data values by or-ing constants and to disassemble them by 
  746. masking and shifting. In that case, use the following definitions.
  747.  
  748. #define timeNMask  0xF8    /* bit mask for the timeNSig field    */
  749. #define timeNShift 3    /* shift count for  timeNSig field    */
  750.  
  751. #define timeDMask  0x07    /* bit mask for the timeDSig field    */
  752.  
  753. Key Signature SEvent
  754.  
  755. An SEvent SID_KeySig sets the key signature for the track. Its data 
  756. field is a UBYTE number encoding a major key:
  757.  
  758. data    key    music notation    data    key    music notation
  759. J0    C maj
  760. J1    G    #    J8    F    b
  761. J2    D    ##    J9    Bb    bb
  762. J3    A    ###    10    Eb    bbb
  763. J4    E    ####    11    Ab    bbbb
  764. J5    B    #####    12    Db    bbbbb
  765. J6    F#    ######    13    Gb    bbbbbb
  766. J7    C#    #######    14    Cb    bbbbbbb
  767.  
  768. A SID_KeySig SEvent changes the key for the following notes in that 
  769. track. C major is the default key in every track before the first 
  770. SID_KeySig SEvent.
  771.  
  772. Dynamic Mark SEvent
  773.  
  774. An SEvent SID_Dynamic represents a dynamic mark like ppp and fff in 
  775. Common Music Notation. Its data field is a MIDI key velocity number 
  776. 0 through 127. This sets a "volume control" for following notes in 
  777. the track. This "track volume control" is scaled by the overall score 
  778. volume in the SHDR chunk.
  779.  
  780. The default dynamic level is 127 (full volume).
  781.  
  782. Set MIDI Channel SEvent
  783.  
  784. The SEvent SID_MIDI_Chnl is for recorder programs to record the set-MIDI-channe
  785. l low level event. The data byte contains a MIDI channel number. Other 
  786. programs should use instrument registers instead.
  787.  
  788. Set MIDI Preset SEvent
  789.  
  790. The SEvent SID_MIDI_Preset is for recorder programs to record the 
  791. set-MIDI-preset low level event. The data byte contains a MIDI preset 
  792. number. Other programs should use instrument registers instead.
  793.  
  794. Instant Music Private SEvents
  795.  
  796. Sixteen SEvents are used for private data for the Instant Music program. 
  797. SID values 144 through 159 are reserved for this purpose. Other programs 
  798. should skip over these SEvents.
  799.  
  800. End-Mark SEvent
  801.  
  802. The SEvent type SID_Mark is reserved for an end marker in working 
  803. memory. This event is never stored in a file. It may be useful if 
  804. you decide to use the filed TRAK format intact in working memory.
  805.  
  806. More SEvents To Be Defined
  807.  
  808. More SEvents can be defined in the future. The sID codes 133 through 
  809. 143 and 160 through 254 are reserved for future needs. Caution: sID 
  810. codes must be allocated by a central "clearinghouse" to avoid conflicts. 
  811. When this SMUS standard passes the "draft" state, Commodore-Amiga 
  812. will be in charge of this activity.
  813.  
  814. The following SEvent types are under consideration and should not 
  815. yet be used.
  816.  
  817. Issue: A "change tempo" SEvent changes tempo during a score. Changing 
  818. the tempo affects all tracks, not just the track containing the change 
  819. tempo event.
  820.  
  821. One possibility is a "scale tempo" SEvent SID_ScaleTempo that rescales 
  822. the global tempo:
  823. currentTempo := globalTempo * (data + 1) / 128
  824.  
  825. This can scale the global tempo (in the SHDR) anywhere from x1/128 
  826. to x2 in roughly 1% increments.
  827.  
  828. An alternative is two events SID_SetHTempo and SID_SetLTempo. SID_SetHTempo 
  829. gives the high byte and SID_SetLTempo gives the low byte of a new 
  830. tempo setting, in 128ths quarter note/minute. SetHTempo automatically 
  831. sets the low byte to 0, so the SetLTempo event isn't needed for course 
  832. settings. In this scheme, the SHDR's tempo is simply a starting tempo.
  833.  
  834. An advantage of SID_ScaleTempo is that the playback program can just 
  835. alter the global tempo to adjust the overall performance time and 
  836. still easily implement tempo variations during the score. But the 
  837. "set tempo" SEvent may be simpler to generate.
  838.  
  839. Issue: The events SID_BeginRepeat and SID_EndRepeat define a repeat 
  840. span for one track. The span of events between a BeginRepeat and an 
  841. EndRepeat is played twice. The SEvent.data field in the BeginRepeat 
  842. event could give an iteration count,1 through 255 times or 0 for "repeat 
  843. forever".
  844.  
  845. Repeat spans can be nested. All repeat spans automatically end at 
  846. the end of the track.
  847.  
  848. An event SID_Ending begins a section like "first ending" or "second 
  849. ending". The SEvent.data field gives the ending number. This SID_Ending 
  850. event only applies to the innermost repeat group. (Consider generalizing 
  851. it.)
  852.  
  853. A more general alternative is a "subtrack" or "subscore" event. A 
  854. "subtrack" event is essentially a "subroutine call" to another series 
  855. of SEvents. This is a nice way to encode all the possible variations 
  856. of repeats, first endings, codas, and such.
  857.  
  858. To define a subtrack, we must demark its start and end. One possibility 
  859. is to define a relative brach-to-subtrack event SID_BSR and a return-from-subtr
  860. ack event SID_RTS. The 8-bit data field in the SID_BSR event can reach 
  861. as far as 512 SEvents. A second possibility is to call a subtrack 
  862. by index number, with an IFF chunk outside the TRAK defining the start 
  863. and end of all subtracks. This is very general since a portion of 
  864. one subtrack can be used as another subtrack. It also models the tape 
  865. recording practice of first "laying down a track" and then selecting 
  866. portions of it to play and repeat. To embody the music theory idea 
  867. of playing a sequence like "ABBA", just compose the "main" track entirely 
  868. of subtrack events. A third possibility is to use a numbered subtrack 
  869. chunk "STRK" for each subroutine.
  870.  
  871.  
  872.  
  873.  
  874. 4. Private Chunks
  875.  
  876. As in any IFF FORM, there can be private chunks in a FORM SMUS that 
  877. are designed for one particular program to store its private information. 
  878. All IFF reader programs skip over unrecognized chunks, so the presense 
  879. of private chunks can't hurt.
  880.  
  881. Instant Music stores some global score information in a chunk of ID 
  882. "IRev".
  883.  
  884.  
  885.  
  886. Appendix A. Quick Reference
  887.  
  888. Type Definitions
  889.  
  890. Here's a collection of the C type definitions in this memo. In the 
  891. "struct" type definitions, fields are filed in the order shown. A 
  892. UBYTE field is packed into an 8-bit byte. Programs should set all 
  893. "pad" fields to 0.
  894.  
  895. #define ID_SMUS MakeID('S', 'M', 'U', 'S')
  896. #define ID_SHDR MakeID('S', 'H', 'D', 'R')
  897.  
  898. typedef struct {
  899.     UWORD tempo;    /* tempo, 128ths quarter note/minute    */
  900.     UBYTE volume;    /* overall playback volume 0 through 127    */
  901.     UBYTE ctTrack;    /* count of tracks in the score    */
  902.     } SScoreHeader;
  903.  
  904. #define ID_NAME MakeID('N', 'A', 'M', 'E')
  905. /* NAME chunk contains a CHAR[], the musical score's name.    */
  906.  
  907. #define ID_Copyright MakeID('(', 'c', ')', ' ')
  908. /* "(c) " chunk contains a CHAR[], the FORM's copyright notice.    */
  909.  
  910. #define ID_AUTH MakeID('A', 'U', 'T', 'H')
  911. /* AUTH chunk contains a CHAR[], the name of the score's author.    */
  912.  
  913. #define ID_ANNO MakeID('A', 'N', 'N', 'O')
  914. /* ANNO chunk contains a CHAR[], author's text annotations.    */
  915.  
  916. #define ID_INS1 MakeID('I', 'N', 'S', '1')
  917.  
  918. /* Values for the RefInstrument field "type".    */
  919. #define INS1_Name 0    /* just use the name; ignore data1, data2    */
  920. #define INS1_MIDI 1    /* <<data1, data2> = MIDI <<channel, preset>    */
  921.  
  922. typedef struct {
  923.     UBYTE register;    /* set this instrument register number    */
  924.     UBYTE type;    /* instrument reference type    */
  925.     UBYTE data1, data2;    /* depends on the "type" field    */
  926.     CHAR  name[];    /* instrument name    */
  927.     } RefInstrument;
  928.  
  929. #define ID_TRAK MakeID('T', 'R', 'A', 'K')
  930. /* TRAK chunk contains an SEvent[].    */
  931.  
  932. /* SEvent: Simple musical event.    */
  933. typedef struct {
  934.     UBYTE sID;    /* SEvent type code    */
  935.     UBYTE data;    /* sID-dependent data    */
  936.     } SEvent;
  937.  
  938. /* SEvent type codes "sID".        */
  939. #define SID_FirstNote     0
  940. #define SID_LastNote    127    /* sIDs in the range SID_FirstNote through
  941.                   * SID_LastNote (sign bit = 0) are notes. The 
  942.                  * sID is the MIDI tone number (pitch).    */
  943. #define SID_Rest        128    /* a rest (same data format as a note).    */
  944.  
  945. #define SID_Instrument  129    /* set instrument number for this 
  946. track.    */
  947. #define SID_TimeSig     130    /* set time signature for this track.    */
  948. #define SID_KeySig      131    /* set key signature for this track.    */
  949. #define SID_Dynamic     132    /* set volume for this track.    */
  950. #define SID_MIDI_Chnl   133    /* set MIDI channel number (sequencers)    */
  951. #define SID_MIDI_Preset 134    /* set MIDI preset number (sequencers)    */
  952.  
  953. /* SID values 144 through 159: reserved for Instant Music SEvents.    */
  954.  
  955. /* Remaining sID values up through 254: reserved for future
  956.  * standardization.        */
  957.  
  958. #define SID_Mark        255    /* sID reserved for an end-mark in RAM.    */
  959.  
  960. /* SID_FirstNote..SID_LastNote, SID_Rest SEvents    */
  961. typedef struct {
  962.     UBYTE    tone;    /* MIDI tone number 0 to 127; 128 = rest    */
  963.     unsigned chord    :1,    /* 1 = a chorded note    */
  964.         tieOut   :1,    /* 1 = tied to the next note or chord    */
  965.         nTuplet  :2,    /* 0 = none, 1 = triplet, 2 = quintuplet,
  966.              * 3 = septuplet    */
  967.         dot      :1,    /* dotted note; multiply duration by 3/2    */
  968.         division :3;    /* basic note duration is 2-division: 0 = whole
  969.                 * note, 1 = half note, 2 = quarter note, I 
  970.              * 7 = 128th note    */
  971.     } SNote;
  972.  
  973. #define noteChord  (1<<<<7)    /* note is chorded to next note    */
  974.  
  975. #define noteTieOut (1<<<<6)    /* tied to next note/chord    */
  976.  
  977. #define noteNShift 4    /* shift count for nTuplet field    */
  978. #define noteN3     (1<<<<noteNShift)    /* note is a triplet    */
  979. #define noteN5     (2<<<<noteNShift)    /* note is a quintuplet    */
  980. #define noteN7     (3<<<<noteNShift)    /* note is a septuplet    */
  981. #define noteNMask  noteN7    /* bit mask for the nTuplet field    */
  982.  
  983. #define noteDot    (1<<<<3)    /* note is dotted    */
  984.  
  985. #define noteD1     0    /* whole note division    */
  986. #define noteD2     1    /* half note division    */
  987. #define noteD4     2    /* quarter note division    */
  988. #define noteD8     3     /* eighth note division    */
  989. #define noteD16    4     /* sixteenth note division    */
  990. #define noteD32    5     /* thirty-secondth note division    */
  991. #define noteD64    6     /* sixty-fourth note division    */
  992. #define noteD128   7     /* 1/128 note division    */
  993. #define noteDMask  noteD128    /* bit mask for the division field    */
  994.  
  995. #define noteDurMask 0x3F    /* mask for combined duration fields    */
  996.  
  997. /* SID_Instrument SEvent        */
  998. /* "data" value is an instrument register number 0 through 255.    */
  999.  
  1000. /* SID_TimeSig SEvent        */
  1001. typedef struct {
  1002.     UBYTE    type;    /* = SID_TimeSig    */
  1003.     unsigned timeNSig :5,    /* time sig. "numerator" is timeNSig + 1 */
  1004.         timeDSig :3;    /* time sig. "denominator" is 2timeDSig:
  1005.                * 0 = whole note, 1 = half note, 2 = quarter      
  1006.              * note, I 7 = 128th note    */
  1007.     } STimeSig;
  1008.  
  1009. #define timeNMask  0xF8    /* bit mask for the timeNSig field    */
  1010. #define timeNShift 3    /* shift count for  timeNSig field    */
  1011.  
  1012. #define timeDMask  0x07    /* bit mask for the timeDSig field    */
  1013.  
  1014. /* SID_KeySig SEvent        */
  1015. /* "data" value 0 = Cmaj; 1 through 7 = G,D,A,E,B,F#,C#;
  1016.  * 8 through 14 = F,Bb,Eb,Ab,Db,Gb,Cb.    */
  1017.  
  1018. /* SID_Dynamic SEvent        */
  1019. /* "data" value is a MIDI key velocity 0..127.    */
  1020.  
  1021. SMUS Regular Expression
  1022.  
  1023. Here's a regular expression summary of the FORM SMUS syntax. This 
  1024. could be an IFF file or part of one.
  1025.  
  1026. SMUS    ::= "FORM" #{    "SMUS" SHDR [NAME] [Copyright] [AUTH] [IRev]
  1027.         ANNO* INS1*  TRAK*  InstrForm* }
  1028.  
  1029. SHDR    ::= "SHDR" #{    SScoreHeader    }
  1030. NAME    ::= "NAME" #{    CHAR*    } [0]
  1031. Copyright    ::= "(c) " #{    CHAR*    } [0]
  1032. AUTH    ::= "AUTH" #{    CHAR*    } [0]
  1033. IRev    ::= "IRev" #{    ...    }
  1034.  
  1035. ANNO    ::= "ANNO" #{    CHAR*    } [0]
  1036. INS1    ::= "INS1" #{    RefInstrument    } [0]
  1037.  
  1038. TRAK    ::= "TRAK" #{    SEvent*    }
  1039.  
  1040. InstrForm    ::= "FORM" #{    ...    }
  1041.  
  1042. The token "#" represents a ckSize LONG count of the following {braced} 
  1043. data bytes. Literal items are shown in "quotes", [square bracket items] 
  1044. are optional, and "*" means 0 or more replications. A sometimes-needed 
  1045. pad byte is shown as "[0]".
  1046.  
  1047. Actually, the order of chunks in a FORM SMUS is not as strict as this 
  1048. regular expression indicates. The SHDR, NAME, Copyright, AUTH, IRev, 
  1049. ANNO, and INS1 chunks may appear in any order, as long as they precede 
  1050. the TRAK chunks.
  1051.  
  1052. The chunk RInstrFormS represents any kind of instrument data FORM 
  1053. embedded in the FORM SMUS. For example, see the document "8SVX" IFF 
  1054. 8-Bit Sampled Voice. Of course, a recipient program will ignore an 
  1055. instrument FORM if it doesn't recognize that FORM type.
  1056.  
  1057.  
  1058.  
  1059. Appendix B. SMUS Example
  1060.  
  1061. Here's a box diagram for a simple example, a SMUS with two instruments 
  1062. and two tracks. Each track contains 1 note event and 1 rest event.
  1063.  
  1064.  
  1065.  
  1066.      +-----------------------------------------+    ------
  1067.      |'FORM'        94               |        ^
  1068.      |    +-----------------------------------+  |      |
  1069.      |  |'SMUS'                    |  |        |
  1070.      |  +-----------------------------------+  |      |
  1071.      |    | +-------------------------------+ |  |      |
  1072.      |    | | 'SHDR'    4          | |  |        |
  1073.      |    | | 12800, 127, 2          | |  |      |
  1074.      |    | +-------------------------------+ |  |      |
  1075.      |    | +-------------------------------+ |  |      |
  1076.      |    | | 'NAME'    10              | |  |        |
  1077.      |    | | 'Fugue in C'          | |  |      |
  1078.      |    | +-------------------------------+ |  |      |
  1079.      |    | +-------------------------------+ |  |      
  1080.      |    | | 'INS1'    9              | |  |      (94 bytes)
  1081.      |    | | 1,0,0,0,'piano'          | |  |       
  1082.      |    | +-------------------------------+ |  |      |
  1083.      |    | 0                    |  |      |
  1084.      |    | +-------------------------------+ |  |      |
  1085.      |    | | 'INS1'    10              | |  |        |
  1086.      |    | | 2,0,0,0,'guitar'          | |  |      |
  1087.      |    | +-------------------------------+ |  |      |
  1088.      |    | +-------------------------------+ |  |      |
  1089.      |    | | 'TRAK'    4              | |  |        |
  1090.      |    | | 60, 16, 128, 16          | |  |      |
  1091.      |    | +-------------------------------+ |  |      |
  1092.      |    | +-------------------------------+ |  |      |
  1093.      |    | | 'TRAK'    4              | |  |       |
  1094.      |    | | 128, 16, 60, 16          | |  |      |
  1095.      |    | +-------------------------------+ |  |      |
  1096.      |    +-----------------------------------+  |      V
  1097.      +-----------------------------------------+    -----
  1098.       
  1099.  
  1100.  
  1101. Appendix B. Standards Committee
  1102.  
  1103. The following people contributed to the design of this IFF standard:
  1104.  
  1105. Bob "Kodiak" Burns, Commodore-Amiga
  1106. R. J. Mical, Commodore-Amiga
  1107. Jerry Morrison, Electronic Arts
  1108. Greg Riker, Electronic Arts
  1109. Steve Shaw, Electronic Arts
  1110. Barry Walsh, Commodore-Amiga
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131. The "0" after the first INS1 chunk is a pad byte.
  1132.  
  1133.  
  1134.  
  1135. Appendix C. Standards Committee
  1136.  
  1137. The following people contributed to the design of this SMUS standard:
  1138.  
  1139. Ralph Bellafatto, Cherry Lane Technologies
  1140. Geoff Brown, Uhuru Sound Software
  1141. Steve Hayes, Electronic Arts
  1142. Jerry Morrison, Electronic Arts
  1143.