Correctly changing the envelope frequency in Pro Tracker 3

ZXNet echo conference «music.zx»

From Ivan Roshin To All 7 December 2000

Hello, All! ═══════════════════ env_freq.1 ══════════════════ (c) Ivan Roshchin, Moscow Fido: 2:5020/689.53 ZXNet: 500:95/462.53 E-mail: asder_ffc@softhome.net WWW: http://www.zx.ru/echo/roschin Correctly changing the envelope frequency in Pro Tracker 3 ─────────────────────────── ─────────────────────────── ("Radio Amateur. Your Computer" 10/2000, 11/2000) Here I want to talk about the disadvantage of the music editor Pro Tracker 3 and how to overcome it. Let's say the melody uses sample, in which for only the envelope (sample) is used to form the sound stuck on position 00): ┌──────────────────── ────────────────────┐ │ EDIT SAMPLE 01 │ │ ▒00 000 -0000 00 --E ............... 0 │ When such a sample sounds, if register R13 is set envelope shape #E, signal at the output of the music coprocessor will look like this (provided graph corresponds to the AY coprocessor, which when used the envelope generates 16 signal levels; on the YM coprocessor 32 levels are formed): A┼ │ │ ▄██▄ ▄██▄ │ ▄██████▄ ▄██████▄ │ ▄██████████▄ ▄██████████▄ │ ▄██████████████▄ ▄██████████████▄│ ▄██████████████████▄ ▄██████████████████▄ │ ▄██████████████████████▄ ▄██████████████████████▄ │ ▄██████████████████████████▄ ▄█████████████████████████ 0└─▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀──▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀─> <─────────── period ───────────> t In one of the melody channels (let it be channel A) let's put a sequence of notes using the discussed sample and with different values of the envelope frequency divider. We get a pattern something like this: │00│003F│..│E-5 1E..│ │01│....│..│--- ....│ │02│....│..│--- ....│ ................... │15│....│..│--- ....│ │16│003C│..│F-5 .E..│ │17│....│..│--- ....│ ................... │31│....│..│--- ....│ │32│0033│..│G-5 .E..│ │33│....│..│--- ....│ ................... │47│....│..│--- ....│ │48│0030│..│A-5 .E..│ │49│....│..│--- ....│ ................... When playing this pattern we will hear in channel A four different sounds successively replacing each other frequencies. This is where the trouble begins: in moments when one soundreplaced by another, a crash is clearly heard. Let's try to figure it out why is this happening. To do this, consider the signal shape at output of the music coprocessor when changing sounds: A┼ │ │ ▄██▄ ▄██▄ ▄██▄ │ ▄█████ ▄████▄ ▄████▄ │ ▄███████ ▄██████▄ ▄██████▄ ▄ │ ▄█████████ ▄████████▄ ▄████████▄ ▄█ │ ▄███████████ ▄██████████▄ ▄██████████▄ ▄██ │ ▄█████████████ ▄████████████▄ ▄████████████▄ ▄███ │ ▄███████████████ ▄██████████████▄ ▄██████████████▄ ▄████ 0└─▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀─▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀──▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──▀▀▀▀▀─> │t moment of sound change It can be seen that at the moment of changing two sounds (namely, at the moment when the number #E is written to the envelope shape register R13) the music coprocessor begins a new envelope cycle, despite that the old cycle has not yet ended. This is the peculiarity coprocessor - it reacts to the very fact of writing to register R13, even if the same number is written there that is already there it was. The graph clearly shows a sharp drop in amplitudes during this moment, which is perceived by ear as a click. At the same time, if you change only the frequency of the envelope, there is no touching R13, the result will be exactly as it should: A┼ ││ ▄██▄ ▄██▄ ▄██▄ │ ▄█████▄ ▄████▄ ▄████▄ │ ▄████████▄ ▄██████▄ ▄██████▄ │ ▄███████████▄ ▄████████▄ ▄████████▄ │ ▄██████████████▄ ▄██████████▄ ▄██████████▄ │ ▄█████████████████▄ ▄████████████▄ ▄████████████▄ │ ▄████████████████████▄ ▄██████████████▄ ▄██████████████▄ 0└─▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀─> │ t момент смены звуков ════════════════════════════════════════════════ С уважением, Иван Рощин. [ZX] [BestView 3.0 - 26%]

From Ivan Roshin To All 7 December 2000

Hello, All! ═══════════════════ env_freq.2 ══════════════════ Well, here's the problem - Pro Tracker does not allow you to install new envelope frequency value without writing the value to the form register envelope. If we try to write it as shown below, Pro Tracker will not "understand" this entry and will not change envelope frequency: │00│003F│..│E-5 1E..│ │01│....│..│--- ....│ │02│....│..│--- ....│ ................... │15│....│..│--- ....│ │16│003C│..│--- ....│ │17│....│..│--- ....│ ................... │31│....│..│--- ....│ │32│0033│..│--- ....│ │33│....│..│--- ....│ ................... │47│....│..│--- ....│ │48│0030│..│--- ....│ │49│....│..│--- ....│ ................... Other music editors may allow this do it, but I just don’t want to switch anywhere from Pro Tracker, because its interface seems to me (and not only me) the most convenient. I listened to a lot of what was written in Pro Tracker melodies and came to the conclusion that their authors came to terms with this, as with something inevitable. At the same time, there is a way to overcome thisproblems that do not require switching to another editor. Let's take advantage of the fact that Pro Tracker has commands increasing and decreasing the value of the envelope frequency divider: 9 - Enable portamento up A - Enable portamento down In position 2 for these commands the delay value is indicated (number of interruptions between two changes), and in positions 3 and 4 indicate the change step. Here is an example of the action of the "9810" command for the case when The initial value of the frequency divider was #0050: divisor ┼ frequencies │ #80 │ ▒▒▒▒▒▒▒▒ #70 │ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ #60 │ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ #50 │█████████████▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ #40 │█████████████▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ #30 │█████████████▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ #20 │█████████████▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ #10 │█████████████▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 0 └─────────────┼───────┼─ ──────┼────────┼───────> x x+8 x+16 x+24 t │ └─the moment the command starts As you can see, after these commands the value of the frequency divider is will change all the time. And we need to adapt these commands to solve the following problem: at the moment of the beginning of a note with an ordinalnumber n change the value of the frequency divider from p1 to p2 if the speed of the melody is s. This can be done as follows: on a note with an ordinal number n-1 we put command 9 if p2>p1, and command A if p1>p2. Command parameters: in the second position we indicate s, and in in positions 3 and 4 we indicate │p2-p1│. Then at the moment when the note with serial number n-1 will end and note n will begin, meaning The frequency divider will change from p1 to p2. In order to stop further changes in the frequency divider to note n set the command 9s00 or As00 (i.e. change in steps of 0). If we apply this method to the example discussed earlier (assuming the melody speed is four), then we we get the following (commands for convenience are given on the right column, in fact, when working in the editor they are not visible): │00│003F│..│E-5 1E..│ │ │01│....│..│--- ....│ │ │02│....│..│--- ....│ │ ................... │15│....│..│---▒....│A403│ (#3F-#3C=3) │16│003C│..│---▒....│9400│ │17│....│..│--- ....│ │ ................... │31│....│..│---▒....│A409│ (#3C-#33=9) │32│0033│..│---▒....│9400│ │33│....│..│--- ....│ │ ...................│47│....│..│---▒....│A403│ (#33-#30=3) │48│0030│..│---▒....│9400│ │49│....│..│--- ....│ │ ................... I recommend downloading Pro Tracker and testing it in practice, how much better the sound became. Now let's look at the case when a melody consisting of of the same single pattern, looped back to the beginning. Please pay pay attention to the fact that for the correct sound you will have to change the above pattern and add another one. After all, if use only the above pattern, then when transitioning to its beginning #E will be written in R13, which means there will be a click is heard. ════════════════════════ ════════════════════════ Best regards, Ivan Roshchin. [ZX] [BestView 3.0 - 26%]

From Ivan Roshin To All 7 December 2000

Hello, All! ═══════════════════ env_freq.3 ══════════════════ So, we get this (the melody should be looped on pattern 1): Pattern 0: │00│003F│..│E-5 1E..│ │ │01│....│..│--- ....│ │ │02│....│..│--- ....│ │ ................... │15│....│..│---▒....│A403│ (#3F-#3C=3) │16│....│..│---▒....│9400│ │17│....│..│--- ....│ │ ................... │31│....│..│---▒....│A409│ (#3C-#33=9) │32│....│..│---▒....│9400│ │33│....│..│--- ....│ │ ................... │47│....│..│---▒....│A403│ (#33-#30=3) │48│....│..│---▒....│9400│ │49│....│..│--- ....│ │ ................... │62│....│..│--- ....│ │ │63│....│..│---▒....│940F│ (#3F-#30=#F) Pattern 1: │00│....│..│---▒....│9400│ │01│....│..│--- ....│ │ │02│....│..│--- ....│ │ ................... │15│....│..│---▒....│A403│ (#3F-#3C=3) │16│....│..│---▒....│9400│ │17│....│..│--- ....│ │ ...................│31│....│..│---▒....│A409│ (#3C-#33=9) │32│....│..│---▒....│9400│ │33│....│..│--- ....│ │ ................... │47│....│..│---▒....│A403│ (#33-#30=3) │48│....│..│---▒....│9400│ │49│....│..│--- ....│ │ ................... │62│....│..│--- ....│ │ │63│....│..│---▒....│940F│ (#3F-#30=#F) As we can see, when using this method the number of patterns in the melody may increase. Yes, and with the calculation of differences and with You'll have to tinker with installing commands, but the sound quality will be it will get much better! I recommend writing the melody first "like usually", not paying attention to the clicks during playback, and then already convert it to the “correct” form. And a few more words: as you may have noticed, the considered sample sounds the same as when used envelope shape #E, as well as when using envelope shape #A. But in the melody it is recommended to use the #E form - as can be seen from the graph when using the #A form at the beginning of the melody a click will be heard due to a sharp change in amplitude: A┼ │ │ █▄ ▄██▄ │ ███▄ ▄██████▄ │ █████▄ ▄██████████▄│ ███████▄ ▄██████████████▄ │ █████████▄ ▄██████████████████▄ │ ███████████▄ ▄██████████████████████▄ │ █████████████▄ ▄██████████████████████████▄ 0└─────────────▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀── ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀─> <─────────── period ───────────> t │ beginning of the melody Well, how can you listen to already written PT3 modules without crashing? without changing anything about them? This can be done using my BestView 2.9 program, turning on the envelope filter (a sign of its activity - '√' icon in the lower right corner of the screen, enable/ switch off - using the "V" key). In version 2.9 the filter only works when playing PT3 modules, so if you want to get rid of the crackling sound when playing modules written in Sound Tracker, S.T.Pro, Pro Tracker 2, then you need them convert to PT3 format (which is successfully done using PT3 itself). In subsequent versions of BestView all these formats will be supported directly. Using this feature, many PT modules began to sound in a new way - for example, the music album "Explosion" by ViSuAl^Extreme. Perhaps some of the readers of this article would like write your own music player, or just add it to your program the ability to play PT3 modules (say, inas background music). In this case, the following The information will certainly be useful. So how does it work this same envelope filter in BestView 2.9? First, let's define the variables used. ENV_FIL (byte) shows whether the filter is enabled (1 - yes, 0 - no). This variable can be changed by the user directly during playback. The Z_FIRST (byte) variable indicates whether a write was made to R13 at least once from the beginning of the melody (1 - yes, 0 - no). She needs it reset before initializing the module. Let's look at a fragment of a standard player of PT3 modules, in in which new values are written to the music registers coprocessor: ...... ....... #C73C: LD B,D #C73D: OUT (C),L #C73F: LD B,E #C740: OUTI #C742: LD A,0 #C744: OR A #C745: JR Z,#C751 #C747: LD B,D ;! #C748: OUT (C),L ;! #C74A: LD B,E ;! #C74B: OUT (C),A ;! #C74D: XOR A #C74E: LD (#C743),A #C751: LD LY,#3A ...... ....... Marked with '!' commands directly record newvalue in R13. Before their execution, the battery contains written value, D=#FF, E=#BF, L=13. Let's put the CALL PATCH command at address #C747. Then how as soon as the player wants to record something in R13, it will be called our PATCH routine. And she will already decide: to record in R13 or not, and if produced, then what exactly should be written there. ════════════════════════ ════════════════════════ Best regards, Ivan Roshchin. [ZX] [BestView 3.0 - 26%]

From Ivan Roshin To All 7 December 2000

Hello, All! ═══════════════════ env_freq.4 ══════════════════ Here is her text with detailed comments: PATCH LD B, D ; these are the same two commands instead of which OUT (C),L ;the player now has CALL PATCH ;If the filter is turned off - write to R13 ;should be (and set Z_FIRST ;in 1): LD B,A LD A,(ENV_FIL) AND A JR Z,SET_ZFS ;Filter is enabled. ;Replacement of envelope shape #A with #E ;(but only if the period is less than #200): LD A,(#C30C) CP 2 JR NC,ENV_NEA LD A,B CP#A JR NZ,ENV_NEA LD B,#E ENV_NEA ;If the call is the first after INIT - ;the entry in R13 should be: LD A,0 Z_FIRST EQU $-1 AND A SET_ZFS LD A,1 LD(Z_FIRST),A LD A,B RET Z ;If the same is not written in R13 ;the value that was there - record ;should be: LD B,D IN B,(C) CP B RET NZ ;If the envelope was previously turned off, ;the entry should be: PUSH AF ;These commands need some LD B,#7F ;explanation. BestView has LD A,SS_BANK ;special variable EN_USED, OUT (C),A ;which changes after eachLD A,(EN_USED) ;calling the PLAY procedure. This re- AND A ;variable is set to 1 if LD A,#10 ;used on any channel OUT (C),A ;envelope, and to 0 if envelope JR NZ,PR_PERI ;not used. At the moment of execution ;the meaning of these commands is therefore ;EN_USED indicates whether it was used ;whether the envelope is before the current call ;PLAY procedures. POP AF RET ;If period >=#200 - the entry should be: PR_PERI LD A,(#C30C) CP 2 JR C,NEN_WKL POP AF RET ;Cancel the entry in R13: NEN_WKL POP AF ;increase the return address by 3 ;(to skip LD B,E: OUT (C),A ;in the player): EX (SP),HL INC HL INC HL INC HL EX (SP),HL RET When playing PT3 modules compiled with the player, I recommend taking the frequency table directly from the module (as is done in BestView). First, the frequency tables in different versions of Pro Tracker 3 are slightly different, and secondly, it is worth considering the possibility that the author of the melody used my own frequency table, not matching with none of the standard ones (for example, I used naturalscale, not tempered). When playing modules compiled without a player, I recommend using frequency tables from Pro Tracker 3.4 final, since it is in this version of the editor that they are calculated with maximum accuracy. It is enough to store in the program only the first 24 bytes of each table, which corresponds to twelve notes of the first octave. For each subsequent octave the frequencies will be twice as much - well, the values ​​in the table are, accordingly, twice less. Considering that there are four tables in total, and each contains values for eight octaves, this will save 4*7*24=672 bytes! This is a lot - especially considering that such tables practically not packed. I also recommend fixing the one in the standard player error processing the vibrato command (see my article "Error in player Pro Tracker 3 and its correction" in the 8th issue of the magazine). To do this, you need to place byte #1D at offset #A34 from start of the player. There is another error in the PT3 player: mixing up the parameters of the vibrato command. Those who want to fix it I recommend reading the article ((c) Max/CBX/BDA) in the ninth issue electronic magazine DEJA VU. ════════════════════════ ════════════════════════ Best regards, Ivan Roshchin. [ZX] [BestView 3.0 - 26%]