So I knew for a long time that both the VRC7 and 5B had some amplifier stuff to be worked out, and it's been on my list to investigate for a long time. I've run a few tests today that had interesting results. I haven't really fully analyzed them, but I thought I should share in case anyone has any good ideas for how to approach testing this stuff.
All mentioned test ROMs are here on github.
1. VRC7 seems to have flat clipping that begins at slightly less than 2x the full volume of 1 channel. This means if I play 2 channels at the loudest volume, there will be some distortion.
The clip_vrc7 test ROM creates a sine wave instrument, plays it on 1 channel at full volume, then 2 at once, then 3 at once, etc. In this recording we can see clipping begins on the bottom part of the wave only at 2x (an internal bias?), and then clipping on both ends at 3x and higher. Finally a triangle wave is overlaid to demonstrate that this clipping only applies to the VRC7 portion of the sound, the input audio appears to be passed through unharmed.
Recording is attached.
2. 5B is much stranger. I don't know how to describe what this is doing. I don't think there is clipping, but there seems to be some sort of compression effect?
The clip_5b test ROM creates 3 squares at 110, 220, 440hz, plays them together at volumes 9,A,B,C where they seem to mix together normally / linearly. Next it starts from 0 and gradually increases volume to 15 for each channel in turn. For the first channel, we see very nice 3db steps like expected, but the very last step to volume 15 isn't quite as wide. As the next two channels fade themselves in, the overall volume does increase a bit, but it seems to be squashed. Finally an APU triangle is overlaid at ~470Hz. This triangle is audible, but when I cut off the 5B squares, suddenly its volume grows? It seems to take about 30ms to reach its full volume after the loud squares have left.
triangle_returns.png [ 5.22 KiB | Viewed 13607 times ]
So, this is a bit bizarre. I guess this is some sort of compressor, but how should I go about trying to test it and properly replicate its behaviour?
Kinda mad at myself for not digging into this sooner. I noticed the compressed look of Gimmick's audio when I recorded its soundtrack a while back, and I even adjusted the log tables in NSFPlay's 5B simulation to match the squashed volumes 15 and 14.5 I had seen in testing (yes, a real hack job for sure). Had a note to go back for it later, but my priorities had been elsewhere for a few years...
(Also, I made a revision to my audio survey test for 5B. Since the output seems reliably linear for a single channel below volume 15, I replaced the full volume test with volume 12. This also meant a revision to the new 'mixe' chunk I'd proposed, but hopefully nobody's actually using it yet.)
Wanted to stack 3 squares of the same pitch in-phase, but being able to phase reset on the 5B continues to elude me. I thought I could get it by setting the period registers to 0 or 1 to get them in a short loop and then setting the final pitch on all 3 very quickly would do it, but this didn't work like I thought it would (phases still seemed "random"). Kinda curious about how they're actually implemented internally... has there been a decap / analysis of the AY at any point?
3. It appears that it's actually possible to reset the VRC7 LFO! Edit: this only applies to tremolo LFO. The vibrato LFO is not reset by this method! Edit again: another method was found which does reset both LFO! See: this post.
lidnariq asked on the wiki what the $E000:6 audio disable bit did. I did an initial test and found that it silenced the audio, and setting that bit appeared to "clear" the custom instrument (not sure what the "clear" values are, since I can't read it back) and any playing tones. Clearing that bit makes it operate again.
Today I tried playing an instrument with tremolo following such a toggle, though, and discovered that it was reliably playing with the same tremolo phase every time!
So, that's not very useful for playing music (since you're basically flipping the whole unit off and on), but I think if I put this into the VRC7 Tuner I might be able to make better progress on the patches that use tremolo/vibratio, since their free-run nature has always made them very difficult to compare with.
I'm not sure how long it takes to go into effect. The lfo_vrc7 test waits about a frame between setting the bit and clearing it, and then another frame before playing the note. (I was being conservative.) My guess is that the delay we use for other VRC7 writes is probably about how long it takes, but at least I've discovered that it can be done.
None of this really matters for Lagrange Point or Gimmick!, since they don't use loud volumes like this. Even homebrew doesn't usually use VRC7/5B at their loudest since they overpower it anyway. This is "subtle" stuff in terms of utility, not really a big problem if an emulator is missing it, but we still want to know don't we? ^_^
(Also, in case anyone is wondering, I haven't seen an effect like this on the other 4 expansions, so I don't think there's any worry of discovering something like this with any of those.)
All mentioned test ROMs are here on github.
1. VRC7 seems to have flat clipping that begins at slightly less than 2x the full volume of 1 channel. This means if I play 2 channels at the loudest volume, there will be some distortion.
The clip_vrc7 test ROM creates a sine wave instrument, plays it on 1 channel at full volume, then 2 at once, then 3 at once, etc. In this recording we can see clipping begins on the bottom part of the wave only at 2x (an internal bias?), and then clipping on both ends at 3x and higher. Finally a triangle wave is overlaid to demonstrate that this clipping only applies to the VRC7 portion of the sound, the input audio appears to be passed through unharmed.
Recording is attached.
2. 5B is much stranger. I don't know how to describe what this is doing. I don't think there is clipping, but there seems to be some sort of compression effect?
The clip_5b test ROM creates 3 squares at 110, 220, 440hz, plays them together at volumes 9,A,B,C where they seem to mix together normally / linearly. Next it starts from 0 and gradually increases volume to 15 for each channel in turn. For the first channel, we see very nice 3db steps like expected, but the very last step to volume 15 isn't quite as wide. As the next two channels fade themselves in, the overall volume does increase a bit, but it seems to be squashed. Finally an APU triangle is overlaid at ~470Hz. This triangle is audible, but when I cut off the 5B squares, suddenly its volume grows? It seems to take about 30ms to reach its full volume after the loud squares have left.
Attachment:
triangle_returns.png [ 5.22 KiB | Viewed 13607 times ]
So, this is a bit bizarre. I guess this is some sort of compressor, but how should I go about trying to test it and properly replicate its behaviour?
Kinda mad at myself for not digging into this sooner. I noticed the compressed look of Gimmick's audio when I recorded its soundtrack a while back, and I even adjusted the log tables in NSFPlay's 5B simulation to match the squashed volumes 15 and 14.5 I had seen in testing (yes, a real hack job for sure). Had a note to go back for it later, but my priorities had been elsewhere for a few years...
(Also, I made a revision to my audio survey test for 5B. Since the output seems reliably linear for a single channel below volume 15, I replaced the full volume test with volume 12. This also meant a revision to the new 'mixe' chunk I'd proposed, but hopefully nobody's actually using it yet.)
Wanted to stack 3 squares of the same pitch in-phase, but being able to phase reset on the 5B continues to elude me. I thought I could get it by setting the period registers to 0 or 1 to get them in a short loop and then setting the final pitch on all 3 very quickly would do it, but this didn't work like I thought it would (phases still seemed "random"). Kinda curious about how they're actually implemented internally... has there been a decap / analysis of the AY at any point?
3. It appears that it's actually possible to reset the VRC7 LFO! Edit: this only applies to tremolo LFO. The vibrato LFO is not reset by this method! Edit again: another method was found which does reset both LFO! See: this post.
lidnariq asked on the wiki what the $E000:6 audio disable bit did. I did an initial test and found that it silenced the audio, and setting that bit appeared to "clear" the custom instrument (not sure what the "clear" values are, since I can't read it back) and any playing tones. Clearing that bit makes it operate again.
Today I tried playing an instrument with tremolo following such a toggle, though, and discovered that it was reliably playing with the same tremolo phase every time!
So, that's not very useful for playing music (since you're basically flipping the whole unit off and on), but I think if I put this into the VRC7 Tuner I might be able to make better progress on the patches that use tremolo/vibratio, since their free-run nature has always made them very difficult to compare with.
I'm not sure how long it takes to go into effect. The lfo_vrc7 test waits about a frame between setting the bit and clearing it, and then another frame before playing the note. (I was being conservative.) My guess is that the delay we use for other VRC7 writes is probably about how long it takes, but at least I've discovered that it can be done.
None of this really matters for Lagrange Point or Gimmick!, since they don't use loud volumes like this. Even homebrew doesn't usually use VRC7/5B at their loudest since they overpower it anyway. This is "subtle" stuff in terms of utility, not really a big problem if an emulator is missing it, but we still want to know don't we? ^_^
(Also, in case anyone is wondering, I haven't seen an effect like this on the other 4 expansions, so I don't think there's any worry of discovering something like this with any of those.)