DMC unsigned samples?
Moderator: Moderators
DMC unsigned samples?
By just sending the value written to the dac (volume), it plays fine, except for an high frequency sound on background. I suspect it's because of +0x40 in every sample. Any ideas of fixing it?
- rainwarrior
- Posts: 8731
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: DMC unsigned samples?
I'm confused by the qualifier "unsigned", because the device is fundamentally an unsigned one. What is this an alternative to?
A fixed bias should be silent, unless you're doing something very strange to your sound; maybe a broken highpass filter of some sort?
Is the high frequency sound a specific frequency? (What frequency?)
A fixed bias should be silent, unless you're doing something very strange to your sound; maybe a broken highpass filter of some sort?
Is the high frequency sound a specific frequency? (What frequency?)
Re: DMC unsigned samples?
You must listen yourself. Here's my wave file.
First part is unsigned; later, signed samples.
First part is unsigned; later, signed samples.
- Attachments
-
- wave_sample.rar
- (310.54 KiB) Downloaded 207 times
Re: DMC unsigned samples?
On the NES, DPCM encoded samples intrinsically always encode an audible error signal.
For a naïve encoder that doesn't try to do any noise shaping (which is to say almost all of them), this error signal is a whine at half the sampling rate.
For a naïve encoder that doesn't try to do any noise shaping (which is to say almost all of them), this error signal is a whine at half the sampling rate.
Re: DMC unsigned samples?
Is possible to remove it & keep the playback as unsigned samples?
Re: DMC unsigned samples?
Why did you use .rar instead of .zip or .7z?
If you're referring to hiss in the drums of the world 2 overworld, that hiss is encoded in the sample itself. I can hear it clearly on my NES through A/V out. I can't hear it so well in RF out because high frequencies are EQ'd so far down. To remove it during playback, you can apply a low-pass filter to the whole mix, as the RF output does.
If you're referring to hiss in the drums of the world 2 overworld, that hiss is encoded in the sample itself. I can hear it clearly on my NES through A/V out. I can't hear it so well in RF out because high frequencies are EQ'd so far down. To remove it during playback, you can apply a low-pass filter to the whole mix, as the RF output does.
Re: DMC unsigned samples?
Yes, you could add an extra fictitious band-stop filter at the Nyquist rate. A two-sample moving average should be adequate (after the delta encoding→linear count conversion, but before resampling to the sound card's native rate). I don't know how audible this lowpass filter would be beyond that: delta encoding is already really bass-heavy.
Re: DMC unsigned samples?
WinRARtepples wrote:Why did you use .rar instead of .zip or .7z?
Okay.tepples wrote:If you're referring to hiss in the drums of the world 2 overworld, that hiss is encoded in the sample itself. I can hear it clearly on my NES through A/V out. I can't hear it so well in RF out because high frequencies are EQ'd so far down.
Re: DMC unsigned samples?
Why is "unsigned" so much quieter than "signed"?Zepper wrote:First part is unsigned; later, signed samples.
Re: DMC unsigned samples?
It depends on whether "unsigned" means from the NES point of view or from the PC point of view. Not knowing which, I shall answer both.
If from the NES point of view: All five 2A03 channels are unsigned, outputting only positive amplitudes. But doing so creates a DC bias in the output, and a high-pass filter is needed to remove this. The audio path in the NES Control Deck includes such a filter.
If from the PC point of view: There are two conventions for representing PCM audio. "Unsigned" uses all positive integers within a built-in bias of half of the range (0 to 255 or 0 to 65535). "Signed" uses signed integers (-128 to 127 or -32768 to 32767). The Allegro 4 library (used for audio output, among other things, in Zepper's RockNES emulator) uses unsigned samples, as does port $4011 on the NES. The Game Boy Advance audio hardware uses signed 8-bit samples. RIFF WAVE files (.wav) traditionally use unsigned 8-bit samples or signed 16-bit samples. To convert from one convention to the other, flip the most significant bit.
If from the NES point of view: All five 2A03 channels are unsigned, outputting only positive amplitudes. But doing so creates a DC bias in the output, and a high-pass filter is needed to remove this. The audio path in the NES Control Deck includes such a filter.
If from the PC point of view: There are two conventions for representing PCM audio. "Unsigned" uses all positive integers within a built-in bias of half of the range (0 to 255 or 0 to 65535). "Signed" uses signed integers (-128 to 127 or -32768 to 32767). The Allegro 4 library (used for audio output, among other things, in Zepper's RockNES emulator) uses unsigned samples, as does port $4011 on the NES. The Game Boy Advance audio hardware uses signed 8-bit samples. RIFF WAVE files (.wav) traditionally use unsigned 8-bit samples or signed 16-bit samples. To convert from one convention to the other, flip the most significant bit.
Re: DMC unsigned samples?
1. Let's take the NES APU sample generation - unsigned samples. The DMC output has an audible hiss caused by a +0x40 factor. Back in old times, the DMC output was value-0x40 to center the wave (signed samples).
2. For PC sample generation, well... Allegro uses unsigned samples (16 bits = 2 bytes per sample), and the emulator generates signed samples. Example: the square wave duty cycle has a volume level (00-0F); for signed samples, the zero part becomes a negative sample. So, a duty cycle 0 1 1 1 1 1 1 0, or in volume levels 00 0f 0f 0f 0f 0f 0f 00 should output as -0f +0f +0f +0f +0f +0f 0f -0f. Argh, in other words:
3. At anyway, the final PC wave is built by value ^ 0x8000 for the Allegro sound wave. I'm not going into this part.
2. For PC sample generation, well... Allegro uses unsigned samples (16 bits = 2 bytes per sample), and the emulator generates signed samples. Example: the square wave duty cycle has a volume level (00-0F); for signed samples, the zero part becomes a negative sample. So, a duty cycle 0 1 1 1 1 1 1 0, or in volume levels 00 0f 0f 0f 0f 0f 0f 00 should output as -0f +0f +0f +0f +0f +0f 0f -0f. Argh, in other words:
Code: Select all
output = 0 != duty ? volume: -volume;
- rainwarrior
- Posts: 8731
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: DMC unsigned samples?
A constant bias is silent. This does not create "an audible hiss". There's no "-0x40" or "+0x40" on the output, centering is accomplished with a highpass filter.Zepper wrote:1. Let's take the NES APU sample generation - unsigned samples. The DMC output has an audible hiss caused by a +0x40 factor. Back in old times, the DMC output was value-0x40 to center the wave (signed samples).
Either the audible hiss is caused by something else, or something is very broken in your audio output if you think adding or subtracting 64 to the output affects it.
Re: DMC unsigned samples?
Yeah, you need to add in the "world's simplest highpass filter". This post may contain mistakes or errors, and is psuedocode done from memory...
Stage 1: Instead of using actual volume samples, deal in differences between current sample and last sample.
For example, some square wave might be like 0,0,0,0,32,32,32,32,0,0,0,0,32,32,32,32...
Instead express it as 0,0,0,0,32,0,0,0,-32,0,0,0,32,0,0,0...
Then when you want to output actual samples, you would do something like this:
int wave_value
wave_value += wave_change << 24
output_wave[x] = wave_value >> 16
bonus: you can prevent overflows on wave_value easily this way.
Stage 2: The actual highpass filter itself
you can do wave_value = wave_value - (wave_value >> 24) after every sample to make it slowly decay to zero, this will eliminate DC biases. You still add the wave changes to wave_value as normal.
Note: not sure on the actual numbers for the filter. Someone else please fix my mistakes...
Stage 1: Instead of using actual volume samples, deal in differences between current sample and last sample.
For example, some square wave might be like 0,0,0,0,32,32,32,32,0,0,0,0,32,32,32,32...
Instead express it as 0,0,0,0,32,0,0,0,-32,0,0,0,32,0,0,0...
Then when you want to output actual samples, you would do something like this:
int wave_value
wave_value += wave_change << 24
output_wave[x] = wave_value >> 16
bonus: you can prevent overflows on wave_value easily this way.
Stage 2: The actual highpass filter itself
you can do wave_value = wave_value - (wave_value >> 24) after every sample to make it slowly decay to zero, this will eliminate DC biases. You still add the wave changes to wave_value as normal.
Note: not sure on the actual numbers for the filter. Someone else please fix my mistakes...
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: DMC unsigned samples?
File 001.wav - first half plays signed samples (filtered); next half plays unsigned samples.
File 007.wav plays 4011_value-0x40 (center-line).
File 007.wav plays 4011_value-0x40 (center-line).
- Attachments
-
- SMB3_wav.zip
- (463.55 KiB) Downloaded 168 times
- rainwarrior
- Posts: 8731
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: DMC unsigned samples?
Between the samples played in this SMB3 recording should be silence where they stop. When a sample is finished playing, the DMC will be outputting a flat signal, which is not what you have, here. In your 001.wav there is a constant whine at ~13700 hz, and it never stops.
I don't think this whine is related to the intrinsic DPCM samplerate, otherwise it would change pitch between the two samples being played, because they use different DPCM frequencies.
I would guess that you have a problem with your oversampling/downsampling method (or some other post-processing you're doing), and somehow this problem manifests differently depending on this bias you've applied. I think this "-0x40" kludge you keep suggesting is probably just a bandaid on a problem that's not directly to do with the DPCM.
The amplitude of the whine seems to be directly related to the current magnitude of the signal. Your 007.wav still has the whine, it's just quieter because you moved the signal closer to 0. The problem is not that the signal is biased, you're just making the problem quieter-- what you need to do is eliminate the cause, and this "-0x40" idea just isn't going to do that. I think you need to look outside your DPCM implementation. This idea about "signed" or "unsigned" DPCM samples is a red herring. The bias shouldn't make an audible difference; there is something else wrong with your audio processing.
Don't worry about highpass filters yet. They're not going to fix the problem either, they're just how an NES would actually centre the waveform. The bias isn't the problem here, though, so implementing a highpass filter won't help. Similarly, implementing a lowpass filter to remove the whine is also incorrect (might hide the problem, but also kills other frequencies that aren't part of the problem). Fix the whine first, leave the filters out until you can get rid of it.
I don't think this whine is related to the intrinsic DPCM samplerate, otherwise it would change pitch between the two samples being played, because they use different DPCM frequencies.
I would guess that you have a problem with your oversampling/downsampling method (or some other post-processing you're doing), and somehow this problem manifests differently depending on this bias you've applied. I think this "-0x40" kludge you keep suggesting is probably just a bandaid on a problem that's not directly to do with the DPCM.
The amplitude of the whine seems to be directly related to the current magnitude of the signal. Your 007.wav still has the whine, it's just quieter because you moved the signal closer to 0. The problem is not that the signal is biased, you're just making the problem quieter-- what you need to do is eliminate the cause, and this "-0x40" idea just isn't going to do that. I think you need to look outside your DPCM implementation. This idea about "signed" or "unsigned" DPCM samples is a red herring. The bias shouldn't make an audible difference; there is something else wrong with your audio processing.
Don't worry about highpass filters yet. They're not going to fix the problem either, they're just how an NES would actually centre the waveform. The bias isn't the problem here, though, so implementing a highpass filter won't help. Similarly, implementing a lowpass filter to remove the whine is also incorrect (might hide the problem, but also kills other frequencies that aren't part of the problem). Fix the whine first, leave the filters out until you can get rid of it.