How to remove noise from digitized samples?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
How to remove noise from digitized samples?
by on (#173568)
I have the problem that whenever I convert a wave file with digitized speech to FamiTracker and lower the quality (since I have to make it smaller for my game, so I can't use full quality), there's always a high frequency sound in the background.

I attached an example zip archive that contains the following files:
The original wave file that was used for the FamiTracker import.
The FamiTracker file.
And a wave file of a recording of what the FamiTracker file sounds like (in case you don't feel like starting FamiTracker to hear it).

This is a general problem that I have with all wave files that I tried.

The noise is even visible in the preview window as a big, fat straight line:
Attachment:
Noise.png
Noise.png [ 20.13 KiB | Viewed 4526 times ]


How can I remove this? Are there any NES-related tools to alter the sample file directly or is there any way to prepare the original source wave file, so that it works for an NES sample?
Re: How to remove noise from digitized samples?
by on (#173569)
The DPCM channel can only represent silence by railing (i.e. going to 0 or 126) or stopping. Otherwise, the quietest idle value is -36dBFS.

Correspondingly, you could either manually edit the source file to go to + or - full scale during silences during the recording (with the understanding that this may add an audible click); you could slice up the file into multiple segments; or you could intentionally add a sound that would be acceptable in the background instead.
Re: How to remove noise from digitized samples?
by on (#173570)
The automatic DMC playback can't produce a constant volume level because each bit makes the waveform go either up or down. In the silent parts of your sample you have $55 = %0101_0101. At pitch 8 each bit plays for 190 CPU cycles, so the period of the 0,1,0,1,... waveform is 380 CPU cycles. If you calculate the corresponding frequency, it's around 4500 Hz, well within audible range.

One solution is to split the sample into multiple parts, cutting out the silent parts. Then use the DMC IRQ to glue them together (with some delays for the silent parts).

EDIT: lidnariq pointed out that silence is possible by saturating to 0 or 127, but that's usually not very practical.
Re: How to remove noise from digitized samples?
by on (#173571)
That squeal at the Nyquist rate is the result of granularity, an artifact inherent in delta modulation. Because there's no way to specify that the wave stays at the same level from one sample to the next, the converter represents silence by alternating between two adjacent levels.

When I covered "Breaking the Law" for Famicompo Pico 2015, I wrote a program in Python that would identify silent parts of the wave, cut them out, log the start time and length of each remaining segment, and pass them to a delta modulation encoder. This not only eliminates granular squeal but compresses each run of silence to just a few bytes. Then I rigged up a short player program that ran alongside Pently (my music engine) and played the samples at the appointed time. But integrating that program's output into your own program might be an issue. How are you planning to play these samples? In an NSF using FamiTracker's engine or otherwise?
Re: How to remove noise from digitized samples?
by on (#173573)
The problem is that the static noise is not only hearable during silence, but also in the middle of the speech.
So, apart from the fact that I don't know how a FamiTracker DMC file is structured and what I'd have to change with a hex editor to remove the noise during silence, this wouldn't be the solution anyway since the noise is still there.

And splitting the file into various parts is too much fiddling with timed code, even if it was just an issue during silence.

Adding a background sound isn't the solution either since I have a very specific sound file that I want to use: The speech sample of my voice actress.
Also, she doesn't really stop talking during the sentence like in the example file. She says only one sentence with four words without a pause. And you still hear the noise throughout the sound.

Just listen to the file in the attachments: It's a constant cheeping from start to finish, not just a replacement for silence. It's just that it's more audible when the rest is silence, but it's always there.

How does "Dance Aerobics" manage to include speech without that background noise?

tepples wrote:
How are you planning to play these samples? In an NSF using FamiTracker's engine or otherwise?

The sample is supposed to be played in my game. It's a little text that the main character says when you press Start on the title screen.
The game uses FamiTone.

And I'd rather not waste any specific program code in the NES ROM for this. I'd prefer a solution that works on the FamiTracker or DMC file directly, so that the correction is done on the data level and is already audible in FamiTracker itself.
Re: How to remove noise from digitized samples?
by on (#173581)
DRW wrote:
And splitting the file into various parts is too much fiddling with timed code, even if it was just an issue during silence.

The player for "Breaking the Law" only counts frames.

Quote:
How does "Dance Aerobics" manage to include speech without that background noise?

You made me get all sweaty to test this ;-)

I'm having trouble getting past the "FOLLOW THESE 4 MOVES" part in lesson 4. It makes me appreciate Konami's invention of the arrow layer and relatively consistent step judging for Dance Dance Revolution, and I look forward to using it come 2019 or so. But I did manage to gather the following differences:

  1. Higher quality. I'm guessing rate C (16884 Hz) or higher, not the 8 (9420 Hz) that your FTM uses. See list of sample rates.
  2. Playing music over it.
  3. Shorter samples (e.g. "C'mon", "Let's go", "One", "Two", etc.) with less silence.

Quote:
And I'd rather not waste any specific program code in the NES ROM for this. I'd prefer a solution that works on the FamiTracker or DMC file directly, so that the correction is done on the data level and is already audible in FamiTracker itself.

Split it into individual syllables and make each syllable the sample for a separate note. Use the Gxx effect to fine-tune the timing of the syllables. Use rate C, not rate 8.
Re: How to remove noise from digitized samples?
by on (#173585)
tepples wrote:
The player for "Breaking the Law" only counts frames.

O.k., but still: I won't dedicate source code to a little sound sample. I'd rather try to fix the data.

tepples wrote:
You made me get all sweaty to test this ;-)

The title screen would have been enough where she says "Come on, let's go."

tepples wrote:
1. Higher quality (I'm guessing rate C or higher, not 8)

Even with quality 13 and highest Gain, you can still hear the noise in the background in my sample file.

tepples wrote:
2. Playing music over it

Doesn't matter. You won't hear a high frequency noise even if you disable all sound channels except DPCM.

tepples wrote:
3. Shorter samples (e.g. "C'mon", "Let's go", "One", "Two", etc.)

Unless "shorter samples" is supposed to mean "therefore, they could afford a higher quality" (which would just be a repetition of your first point), then again: It doesn't matter. If the high frequency noise is heard throughout the whole sound effect, why should it matter if the sound effect is shorter?

Quote:
Split it into individual syllables and make each syllable the sample for a separate note.

Again: The high frequency noise is not an issue of the moments where the sound is silent. It is a constant noise throughout the whole sound.

In my actual sound sample, my voice actress says "Let's get it on", without any pause and you still hear the noise from start to end.
And in the uploaded sample, the noise is heard in every word.

The noise isn't like this:
Code:
Text:  "The grandpa says   What"
Noise: "   -       -    ---    "


It is like this:
Code:
Text:  "The grandpa says   What"
Noise: "-----------------------"


So, what exactly would splitting the sound do? In the end, it would sound like this:
Code:
Text:  "The grandpa says   What"
Noise: "--- ------- ----   ----"
This would gain me nothing.

It is a constant, never-changing noise. It is not the substitution for silence.
Therefore, any solution that is based on splitting the sound into different parts brings me absolutely nothing. Because the noise is a high-frequency sound that is played throughout the whole file. It is in the background of every word, not just in the pauses.
Re: How to remove noise from digitized samples?
by on (#173586)
DRW wrote:
So, what exactly would splitting the sound do? In the end, it would sound like this:
Code:
Text:  "The grandpa says   What"
Noise: "--- ------- ----   ----"
This would gain me nothing.

It would gain you psychoacoustic masking of the noise. Noise under the sound is less obvious to the player than noise between the sound. Case in point: the laugh in Kung Fu is split into seven samples.

Quote:
It is in the background of every word, not just in the pauses.

If you require that the higher quality be reflected even in FamiTracker, I don't know what to tell you other than to use a higher sample rate. And if using a higher sample rate causes your program to overflow 32768 bytes of PRG ROM, then use a mapper other than NROM to gain more space in $C000-$FFFF.

Accept the noise, use a mapper, or optimize other parts of your program for size. It's an engineering tradeoff.

You mentioned quality 13. If you are willing to optimize other parts of your program for size in order to allow use of quality 13, I will perform additional tests to see what can be done to reduce noise in non-silent segments assuming quality 13.
Re: How to remove noise from digitized samples?
by on (#173588)
So, you tell me that there's no way whatsoever, none at all, to remove that noise if I import a wave file with a lower quality than 14.
Even if I record half a second of total silence (i.e. starting the audio recorder in Windows without any input source), import it into FamiTracker and have that constant noise, there would be no tool to remove that noise from the DMC file afterwards?
Re: How to remove noise from digitized samples?
by on (#173590)
Try the following:
* Lowpass the source file with a relatively low corner frequency. (DPCM can represent low frequencies louder than higher frequencies; pre-encoding to match helps)
* Compand the daylights out of your source file. You want the encoded DPCM to be always sitting right at the edge of slew rate distortion in order to avert quantization noise
* Mix in a relatively loud white noise source (roughly -30dBFS), dramatically raising the noise floor.
* Then finally do the conversion

I make no guarantees that you'll find the results acceptable, but it will give you a set of trade-offs that you can choose to make.

Famitracker's DPCM files are the raw DPCM data that will be streamed to the NES APU.
Re: How to remove noise from digitized samples?
by on (#173592)
I second "Compand the daylights". I used 3:1 level compression in Audacity to reduce the dynamic range. I've attached the level-compressed wave file, as well as FTM and NSF converted with quality 10, 12, and 13.
Re: How to remove noise from digitized samples?
by on (#173594)
Since I hear the noise even if I import a completely silent wave file into FamiTracker (i.e. the noise is basically independent from anything inside the actual file), isn't there a way to remove it from the DPCM sample itself?

I mean, I can try out your above suggestions (if you can name me a tool that supports it since I don't know anything about sound editing).

But since this noise even appears when I feed FamiTracker with a file of two seconds of "nothingness", it's obviously nothing from the wave file itself that produces the sound. So it will always be kind of there, no matter what tricks I apply to the wave file.
So, the only thing I could try is to drown it out, but it will never really go away, unless I use quality 15.

In the case of tepples' altered examples, I still hear the noise even at quality 13.

But since I try to compress a one second file to 2 KB at max (not the one from the example file, by the way), quality 15 is totally out of the question.

So, is there really no way to remove that noise directly in the converted DMC file?
Re: How to remove noise from digitized samples?
by on (#173596)
Not while retaining FamiTracker compatibility. DPCM is a very primitive codec dating back to 1950, and I imagine that Nintendo chose it because it could be implemented in the 2A03 with few gates while not infringing any patents that subsisted as of 1983.

An audio codec could be created that gives quality equivalent to DPCM quality 15 at a much smaller size for voice signals. But then that would involve "specific program code", and it'd take nearly 100% of CPU time to play. You said earlier[1] that you don't want programming help on this project unless it's a preexisting library. I have some ideas on how to make a low-bitrate voice codec with a player library for the NES. But unfortunately, I haven't yet got around to it, and I am currently occupied with another paid project.


[1]Private communication, early December 2015
Re: How to remove noise from digitized samples?
by on (#173598)
tepples wrote:
Not while retaining FamiTracker compatibility.

So there's no kind of waveform editor?

Something where I could remove this part of the sound?
Attachment:
Waveform.png
Waveform.png [ 19.96 KiB | Viewed 4457 times ]


tepples wrote:
But then that would involve "specific program code"

Right, and I cannot afford to include some codec just for playing one voice sample in the title screen that was intended as a neat little gag. I need that room for actual gameplay stuff and of course for the sound sample itself. In the moment, the sound is merely at quality 10. More stuff in the game means an even lower quality. So, yeah, I still hope to find a solution for this without having to include new dedicated code.
Re: How to remove noise from digitized samples?
by on (#173599)
DRW wrote:
So, is there really no way to remove that noise directly in the converted DMC file?
No, it is an intrinsic property of the encoding.

DPCM will always have noise content at the Nyquist rate unless you intentionally add other noise to displace it and will regardless always have noise content at the sample rate.
Re: How to remove noise from digitized samples?
by on (#173600)
Well, that sucks big time.
Re: How to remove noise from digitized samples?
by on (#173603)
Anyway, I said that you could exchange the squeal at the Nyquist frequency with some other noise. Here's an example. You probably won't like it.
Attachment:
demo.ogg [16.1 KiB]
Downloaded 129 times
All I did was add -40dBFS blue noise¹ to your wav before converting it.
¹ specifically, -40dBFS white noise followed by a first-order highpass at 8kHz
Re: How to remove noise from digitized samples?
by on (#173604)
Being fairly experienced with NES/Famicom music I've run into this issue quite a few times.

My suggestion to you would be:
1.) Chop up the samples and leave the silence up to timing.
2.) While the samples are playing, have the noise channel playing long-pattern white noise at a relatively high frequency at a mid-grade to low volume.
Re: How to remove noise from digitized samples?
by on (#173624)
B00daW wrote:
While the samples are playing, have the noise channel playing long-pattern white noise at a relatively high frequency at a mid-grade to low volume.

Since I didn't do the soundtrack myself, but had a composer, and since I use FamiTone for the game itself and I therefore don't know much about all that stuff, can you please provide me an FTM file with an example of the noise channel making the sounds that you describe?
Re: How to remove noise from digitized samples?
by on (#175453)
Noise channel, note C, volume 1. At least that's what Dance Aerobics appears to do.
Re: How to remove noise from digitized samples?
by on (#175460)
Thanks.

In the meantime, I optimized my code and got a good amount of ROM space back. There's still one character to implement, but in the moment, I'm speculating on the possibility that I'll actually manage to include my sample with maximum quality.