Silent notes

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Silent notes

Post by Celius » Wed Sep 03, 2008 11:39 am

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.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Sep 03, 2008 2:15 pm

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.

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Wed Sep 03, 2008 3:56 pm

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.

Roth
Posts: 399
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth » Wed Sep 03, 2008 4:02 pm

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.

jsr
Posts: 42
Joined: Thu Oct 07, 2004 2:47 am
Contact:

Post by jsr » Wed Sep 03, 2008 4:27 pm

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.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Wed Sep 03, 2008 4:28 pm

$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.

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Wed Sep 03, 2008 6:35 pm

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 =).

User avatar
Bregalad
Posts: 7766
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Thu Sep 04, 2008 12:57 am

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)
Life is complex: it has both real and imaginary components.

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Thu Sep 04, 2008 1:12 am

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...

Post Reply