Language…
8 users online: crocodileman94, isaix, Jordan, Maw, obiet,  patcdr, Shiki_Makiro, underway - Guests: 261 - Bots: 353
Users: 64,795 (2,377 active)
Latest user: mathew

What is the qxx command for?

What is the use of the qxx command because in the readme I don't quite understand why it should be used.
The first x handles how long the notes are held. 0 being the shortest, 7 being the longest.

The second x handles the volume from 0~F, and it is proportional to vXXX's value (i.e. if both q's volume value and vXXX value are both very low, then theoretically it's incredibly soft).

By default, both of those values of q are set at their highest point.
Originally posted by brickblock369
The first x handles how long the notes are held. 0 being the shortest, 7 being the longest.

The second x handles the volume from 0~F, and it is proportional to vXXX's value (i.e. if both q's volume value and vXXX value is low, then theoretically it's incredibly soft).

By default, both of those values of q are set at their highest point.


ok, but there are equivalences in the maintenance of the note? I do not know if I explain myself, can you put notes 1/16?

In the second x i dont have doubts.
From what I've estimated ($F4$02 being enabled as that maximizes it):

q0: 0.1875
q1: 0.375
q2: 0.5
q3: 0.53125
q4: 0.5625
q5: 0.8125
q6: 0.875
q7: 0.96875

And yes, even the highest value does not sustain the note all the way, that's just the way AMK handles it.

Edit: I probably miscalculated one of them, probably q5.
Hmm, I always thought that q0 made the note sustain for 1/8 of its duration, q1 made it sustain for 2/8 etc. until you got to q7, which hypothetically would sustain the note for 8/8 of its duration, or in other words, play it completely without cutting it.

Afaik, if you use q7, but don't use $f4 $02, amk will always leave a gap of 2 ticks between notes. If you use $f4 $02, the gap will be 1 tick.

I have a suspicion that this changes as the number of channels increases, for instance the gap feels slightly larger as you add channels.

I should investigate.
Make more of less, that way you won't make less of more!
The volume part (aka the second number in qXY) is used as an index to a table to determine what the actual channel volume is. The table is this one:
Code
VelocityValues:
	db $08, $12, $1B, $24, $2C, $35, $3E, $47, $51, $5A, $62, $6B, $7D, $8F, $A1, $B3	; Normal, SMW velocities.
	db $19, $33, $4C, $66, $72, $7F, $8C, $99, $A5, $B2, $Bf, $CC, $D8, $E5, $F2, $FC	; Standard N-SPC velocities.

The second row is used normally with #amk 2 (or in #amk 1 using the #louder option), and the numbers are divided with $FF (255) and multiplied with the channel volume to get the final result. So for example if you have qX7 with v200, the entry in the table (with N-SPC velocity on) is $99 (153 in decimal), which divided by 255 is 0.6, multiplied by v200 is v120, so that's what the actual volume will be. This also means that, since the v values are not linear, the effect of the volume quantization changes depending on how high or low the v value is.

For the note duration part, the number is used once again as an index to a table that determines how much the actual note duration will be:
Code
NoteDurations:
	db $33, $66, $80, $99, $B3, $CC, $E6, $FF

and once again the formula is the same: divide the value in the table by $FF, multiply the result with the note length. I believe the tick at the end of each note is handled after this step (or two ticks if $F4$02 is not used), because the code doesn't actually "remove a tick", it just performs a check later to see if the channel is on the last (or penultimate without $F4$02) tick, and if yes it keys off the channel.
You can also see that these values are not linear, so for example q2X equals half of the note length. brickblock's results look accurate after taking into account the additional tick that's removed automatically (although since that tick is constant for all note lengths, the proportions change depending on the note length, so if you want to be accurate you should use the values in the table to do the proportion and then subtract 1 or 2 from the result).

Originally posted by musicalman
I have a suspicion that this changes as the number of channels increases, for instance the gap feels slightly larger as you add channels.

This sounds very strange, but who knows, lol.
So just did some testing.
If $f4 $02 is used, there is a gap of 1 tick between notes. Otherwise the gap is 2 ticks.

High channel count seems to increase the gap; when trying to stress test it, I was getting gaps of 2 ticks with $f4 $02, and 3 ticks without it.

Not sure if this increase is predictable eg. always happens with a certain number of channels, a high tempo etc. or is in direct response to how much stress the music is putting on the engine.

In any case this is probably waaay more than the op wanted to know...

Edit: Kevinm wrote his post as I was typing. After reading it, I'd trust his q value chart over mine. But I'll put mine below for posterity or something.
q0: 0.198
q1: 0.396
q2: 0.5
q3: 0.594
q4: 0.698
q5: 0.791
q6: 0.896
q7: 1.0
Make more of less, that way you won't make less of more!
If v values aren't linear, is there some kind of function that shows what sort of curve they follow (if they do follow a curve)?

I notice that the volume part of the q value starts out being separated by 25 or 26 (in decimal) before abruptly cutting the difference in half, to 12/13.
Originally posted by VecchiaZim
If v values aren't linear, is there some kind of function that shows what sort of curve they follow (if they do follow a curve)?

Looking a bit at the code it looks like the volume does follow a curve. The reason is in how the final vXXX value is computed: first, the q value is used to scale v down by a factor determined by the table I posted earlier (which doesn't look like it follows any one pattern), by doing V <- V * VelocityValues[q] / 256. Then the Master volume is used to do the same computation, but using its value directly: V <- V * Master / 256. After all this, there a final step: V <- V*V / 256, and this is what breaks the linearity of the volume command. Then how the V is actually converted to left and right volumes is determined by the pan table, which once again doesn't follow any one curve, but its usage is again a multiplication and then divided by 256 (+ adding in the $FA$03$XX factor at the end to amplify the result).
tl;dr yeah, the channel volume follows a quadratic curve, but the way q affects V doesn't follow a precise rule other than just using the values in the velocity table.

Edit: here I showed V <- V * ... for simplicity, the actual code keeps track of the "V command" value and the "True volume" value in different addresses, and the true volume is what's computed with all these steps and then used at the end.

Edit 2: this also means that it's very easy to find a V such that the overall volume is a certain factor of another V, with this formula: V2 = sqrt(factor) * V1. For example, to get the volume which is half of v200, you do sqrt(0.5) * 200 = 141, and in fact v200 -> 0x2E, v141 -> 0x17 (at w255 q7F). Of course, you can also just use the volume calculation tool in BRRPlayer :P