Silent notes

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Silent notes
by on (#36737)
I'm almost done with my music engine, and I just realized one thing: I haven't done much about shutting a channel up.

Of course, there's always disabling the channel from $4015, but I didn't like this method. I decided to just stick a note value named "Silence" in my music engine so instead of playing, say, a B flat for a quarter note, it would play "Silence" for a quarter note. I do this by storing #$000 into the 11-bit area that determines the pitch.

When I do this, on all the emulators I tested besides FCEUXD (Nintendulator, Nestopia, Nessie, NesterJ), it effectively silences the channel. But on FCEUXD, it just plays an incredibly high pitch. I don't want this. Is there a safe 11-bit value that will effectively silence the channel?

EDIT: Actually, it's only the Triangle wave that's doing it. But like I said, only on FCEUXD. All the other emulators (Besides JNes, which skips notes for some reason) play what I want it to play: complete silence.

by on (#36742)
The triangle channel is never silenced, so playing it at the highest frequencies will make the wave effectively output a flat signal in the middle. This will cause a click almost every time, whereas stopping it won't cause as much. Also, on emulators with imperfect low-pass filtering, you will get awful sounds. I believe Mega Man II uses this technique to silence the triangle, with very clicky results.

by on (#36755)
Okay, well then I guess I'll have to work with silencing the channel through $4015. I'll probably have one of my commands in the music tell the engine to EOR bit 2 of $4015 whenever it needs to be silenced/turned on.

But will it be okay if I use $000 for the square waves? It would just be more space efficient.

by on (#36756)
Is there any special reason that using the bits in $4015 isn't the best way? I use this method to silence out the square channels in the menu selection in the NES prog I'm working on right now. Is there any reason I shouldn't? It seems to work fine for me.

by on (#36757)
Celius wrote:
But will it be okay if I use $000 for the square waves? It would just be more space efficient.


That's okay because the sweep unit makes the the channel silent whenever the period is less than 8.

by on (#36758)
$4015 silences the same way a zero length counter does. For squares and noise, it's like setting volume to 0. For triangle, it stops clocking the waveform, without affecting where it is in the wave. For squares, setting a period of 7 or less also acts like setting the volume to 0.

Celius, why does the triangle channel's differing behavior affect how you store your music? Just have a special case in your code for the triangle that silences it differently when you use period 0. This separates implementation issues from the interface (data format), improving modularity of your system.

by on (#36763)
Roth wrote:
Is there any special reason that using the bits in $4015 isn't the best way? I use this method to silence out the square channels in the menu selection in the NES prog I'm working on right now. Is there any reason I shouldn't? It seems to work fine for me.


I think it's just easier to leave all channels active, so I won't ever have to turn them off and on. Also, for each channel, I have command bytes. Each bit represents what I want to update. If bit 0 is set, it signifies that another command byte with less common features is to be read. The downside to using this extra byte is it takes up more space, so I use it for uncommon updates. For each square wave, the bits in the first command byte represent the most commonly updated things. All of these are used up with really really essential things, so I can't have a bit that tells the engine to shut the channel off/turn it on in the first byte, and it's too common to put in the second command byte. But for the triangle wave, since I can't do anything with volume besides shut the channel off, I could have some bits open to put it in. Space and time would be the issues for me, which basically gives me no point to do it. If it works for you, there's no reason you shouldn't do it. There's just no reason I should do it.


But I probably will do what blargg suggested; that's a very good idea! Thanks for your help guys =).

by on (#36776)
The zero period thing works on squares and triangle channels (altough thanks to the analog filter on triangle), but NOT on noise channel so I guess it's no good idea.
The proper way to disable triangle (assuming you're not using the linear timer) is to write $80 to $4008 and your favourite value greater than $80 to enable it.
Another approach is to use the linear timer to disable it when you want to, so you don't even have to insert silent notes as the channel silent itself after a while (write any value below $80 to $4008)

by on (#36779)
I don't use any hardware envelopes/sweeps in my engine at all, so I wouldn't do the linear timing thing. Doing pure software envelopes/sweeps gives me enough control.

I updated my engine though. It works great! For the triangle, I silence the channel with $000 is put in. For the noise, the only register I really update is $400E. Since bits 7, and 3-0 determine the sound, I made my engine silence the noise channel if bit 4 is set since it's unused. So my music engine is complete! Unless I want to add more features...