These are compiled modules of ASC Sound Master (Advanced Sound Master, ASM) versions 1.xx and 2.x, a project of Andrey Sendetsky (ASC).
This editor appeared at a time when Sound Tracker had already gained wide popularity. The possibilities of ASM in comparison with this single competitor shocked the imagination of musicians of the first half of the 90s. Many were about to switch to ASM, but not many actually did it.
So what opportunities attracted musicians, and which ones scared them so much that many remained on Sound Tracker, and then enthusiastically switched to Pro Tracker, despite the fact that ASC Sound Master existed all this time? Let's figure it out.
First of all, ASM is a professional and well-thought-out tool. He was years ahead of the capabilities of such a powerful editor as Pro Tracker 3.
It's 1992, and ASM already can:
At the same time, the samples and ornaments themselves are not simple (not to mention that there are more of them than in Sound Tracker). The samples have an envelope mask, a volume increase/attenuation, tone, noise and envelopes frequency shifts accumulation. There are accumulations of shifts in both tone and noise in the ornament.
It's impressive even now, when most musicians have chosen Pro Tracker 3 and still use it in the form of Vortex Tracker II. And it's impressive because some of the ASM features have not been implemented in PT3 (or implemented worse).
But if everything is so good, why hasn't ASM replaced ST? And why it less popular than other projects?
Disadvantages of the editor:
Features such as a slow player of compiled modules, an artificial tempo limit (at least 3) or an envelope period without high byte are unlikely to be disadvantages (especially those that scare away musicians).
But the rejection of TR-DOS (or at least the choice of the tape-recording possibility) in favor of its own file system is already serious. Nowhere, except in the editor, can the contents of the disk be viewed, formatted, or tried to restore the unreadable, or make a backup copy. The risk of losing recorded music, not having the usual instruments that are available under TR-DOS, could well affect popularity. Before writing music, it was necessary to prepare discs specifically for ASM and only for ASM, to deal with formatting and other subtleties of working with them. It is not difficult for an average programmer to deal with this, but for a simple musician who has barely mastered the same ST and even for compilation resorting to the help of a coder friend, this is a problem. Unfortunately, the versions of the editor in which enthusiasts taught ASM to work with TR-DOS appeared too late.
It is difficult for anyone to think with accumulations alone to create a sample or an ornament. A human is used to working with absolute values, as in Sound Tracker. And although beautiful concise solutions are obtained with accumulations, you need to tinker a lot to get what you have in mind, and even correctly looped, and not floated down or up. The compromise solution implemented in PT3 is suitable for many: when necessary, accumulations are used, when not, just set the tone and envelope deviations almost at random and nothing will float anywhere.
ASM is generally hard to imagine as the first editor in the life of a musician. The possibilities of the editor are almost limitless, and the initial fuse may not be enough to master it.
The structure of the ASC module can be called traditional with a few exceptions: the offsets inside the structures (patterns, samples, ornaments) are stored not from the beginning of the module, but from the beginning of this structure. Thus, it is possible to move or swap structures without recalculating the offsets inside these structures.
Offset | Size | Designation | Description |
---|---|---|---|
+0 | 1 | Delay | The initial minimum number of interrupts between adjacent notes |
+1 | 1 | LoopPos | Position in the positions list from that the playback will looped |
+2 | 2 | PatPtrs_Ptr | Offset from +0 to the PatPtrs table |
+4 | 2 | SamPtrs_Ptr | Offset from +0 to the SamPtrs table |
+6 | 2 | OrnPtrs_Ptr | Offset from +0 to the OrnPtrs table |
+8 | 1 | PosLst_Len | Number of positions in the positions list |
+9 | PosLst_Len | PosLst | Positions list (pattern numbers in order of playing) |
+PatPtrs_Ptr | 6*PatQty | PatPtrs | Offset table from +PatPtrs_Ptr to each pattern channel descriptor PatChn (described below); PatQty is a quantity of patterns |
+PatPtrs_Ptr+6*PatQty | ? | PatChns | The descriptors of each PatChn |
+SamPtrs_Ptr | 64 | SamPtrs | 32 offsets from +SamPtrs_Ptr to each Sam sample (described below) |
+SamPtrs_Ptr+64 | ? | Sams | All Sams one after the other |
+OrnPtrs_Ptr | 64 | OrnPtrs | 32 offsets from +OrnPtrs_Ptr to each Orn ornament (described below) |
+OrnPtrs_Ptr+64 | ? | Orns | All Orns one after another |
The channel is described by a string of bytes ending with 0xff. The pattern consists of three channels (one offset to each descriptor per channel). This approach is used in most trackers, it allows you not to store the same channel descriptors in the compiled module.
The following is a description of the bytes in the sequence, optional bytes are indicated in square brackets. Undescribed bytes are ignored.
Bytes | Description |
---|---|
0x00..0x55, [Env] | Set a note. Initialize the sample and/or ornament (if allowed). Set low byte of the envelope period to Env (if enabled). Exit. |
0x56..0x5d | Exit. |
0x5e | Break the sample loop: finish playing the current loop and then play 'release' part (described below). Exit. |
0x5f | Turn off the sound. Exit. |
0x60..0x9f | From now on skip the specified number of lines (0..63). 0 by default. |
0xa0..0xbf | Set the sample 0..31. |
0xc0..0xdf | Set the ornament 0..31. |
0xe0 | Set the channel volume 15. Turn on the envelope. |
0xe1..0xef | Set the channel volume (1..15). Turn off the envelope. |
0xf0, Noise | Set the base for the noise period. |
0xf1 | Prohibit sample initialization in the current line of the pattern. |
0xf2 | Prohibit initialization of the ornament in the current line of the pattern. |
0xf3 | Prohibit initialization of the sample and ornament in the current line of the pattern. |
0xf4, Delay | Set a new playback speed value (Delay in interrupts). |
0xf5, Slide | Set the amount of the tone change per interrupt for the slide down (Slide is a signed number). |
0xf6, Slide | Set the amount of the tone change per interrupt for the slide up (Slide is a signed number). |
0xf7, Ticks | Do 'Portamento' from the previous note during Ticks interrupts without initializing the sample. The calculation is carried out in fractions of units of tone period registers with an accuracy of 1/16. Immediately after these bytes there should be a byte of note setting (0x00..0x55). |
0xf8 | Set the envelope type to 8. |
0xf9, Ticks | Is similar to 0xf7, but with initializing the sample. |
0xfa | Set the envelope type to 10. |
0xfb, AmpDelay | Run a periodic increase or decrease the sample amplitude by 1. Bits 0–4 is the period (1..31) of changes, in interrupts; bit 5: 0 for increase; 1 for decrease. |
0xfñ | Set the envelope type 12. |
0xfe | Set the envelope type 14. |
The sample structure, unlike many other trackers, does not provide separate bytes storing the length and loop point. Instead, the corresponding bit flags are used right in the body of the sample tick.
Moreover, a sample in ASC Sound Master can be divided into three parts using such flags: attack (pressing), loop (cycle), release (releasing). This approach is not implemented in any other tracker on the ZX Spectrum (with the exception of PSC).
So, the sample in ASC consists of ticks of three bytes each, the tick structure is as follows:
Offset | Description |
---|---|
+0 | Bit 7: 1 if this tick is a looping point. Bit 6: 1 if this tick is the last tick in the loop body. Bit 5: 1 if this tick is the last tick in the sample. Bits 4–0 is accumulation of envelope deviation, if envelopes are allowed in this tick, or of the noise period otherwise (high bit is signed). |
+1 | Accumulation of tone period deviation (a signed number). |
+2 | Bits 7–4 is the amplitude. Bit 3 is the noise mask. Bits 2–1: 0, 2, 4 for prohibit the envelope; 1 for allow the envelope; 2 for amplitude decrease by 1; 3 for amplitude increase by 1. Bit 0 is the tone mask. |
If the last tick of the loop body is not marked in the sample, then the sample is considered not looped, it will play to the last tick and will mute.
The accumulation of the amplitude (from the sample and/or from the track command) is performed in the range of -15..+15 in order to ensure that any amplitude in the sample can be muted or maximized.
The ornament uses the same approach of marking ticks with bit flags. Unlike a sample, the loop end bit is simultaneously a marker of the last tick, so its presence is mandatory. Each tick of the ornament is two bytes, its structure:
Offset | Description |
---|---|
+0 | Bit 7: 1 if this tick is a looping point. Bit 6: 1 if this tick is the last tick of the ornament. Bits 4–0 is accumulation of the noise period deviation (high bit is signed). |
+1 | Accumulation of the note offset in semitones (a number with a sign). |
The description of the STP format mentions the problem of storing the author string of the first tracker music editors on the ZX Spectrum. The roots of this problem are in the ASC Sound Master editor.
The appearance of the ASC Sound Master editor influenced the thought course of not only programmers who were considering their music editor project, but also many ordinary users in general. The stereotype emergence that the player and the module are one, was largely facilitated by the fact that when compiling a module, the player is always added to it in ASC Sound Master. As a consequence of this approach, it seemed to many not contrary to logic that the line with the names of the module and of its author is stored in the player body.
When the same player, differing only in the author string, is glued to each module, there inevitably comes a moment of understanding that this is at least wasteful (if we are talking about a collection of modules on a floppy disk), and at most limits the possibilities (if we are talking about trying to load a certain number of modules into the computer's RAM at the same time).
The solutions applied by some led to problems: just cutting off the player made the ASM modules nameless (which repeated the Sound Tracker problem), and using one player for several modules in the program left the unsolvable question of which module exactly for the author string in the player.
The source string in the player has a fixed size of 63 bytes, its structure is as follows: "ASM COMPILATION OF <NAME> BY <AUTHOR>" (all spaces are important, the length of <NAME> is the same as <AUTHOR> and is equal to 20 ASCII characters, as a result, the position of the tag " BY " fixed).
The Ay_Emul author considered several options for saving the name of the ASM module. But the variant proposed by Ilya Kudryavtsev from Izhevsk (Himik's ZXZ), the author of the spectrum ripper and music player Pusher, turned out to be the most optimal.
To insert a string into the body of the ASC module, you must:
Due to described above the property of offsets within ASC structures, modification of other pointers is not required.
In order to insert the author string from the player into the body of the module, it is enough to load the module with the player into Ay_Emul and save it from the playlist or use the "Search for tunes in files" tool. In the second case, two variants will get: with and without a tag.
If you manually pull a text like "ASM COMPILATION OF LET'S DANCE, BABY ! BY ANDREW SENDETSKI ASC", then you can insert it into the comment of the playlist item, and then save the ASC from the playlist window, and, if there is no string in the source file yet, it will be inserted.