6
$\begingroup$

I'm completely new to the world of audio and signals. I noticed that when I opened Audacity and generated one second of silence (details below) and converted the raw WAVE file to a list of integers, that the silence wasn't a bunch of zeroes. (Yes, I was sure to convert the endianness.)

It was a series of seemingly random numbers from -7 to +7. (It was 16-bit signed PCM.)

Generated by:

  • Open Audacity
  • Click Generate > Silence...
  • Set duration to 00h00m01.000s
  • Click OK
  • Click File > Export > Export as WAV
  • Enter a file name
  • Specify encoding as "signed 16-bit PCM"
  • Click Save
  • Open the generated file with a program that lists each chunk as a list of signed 16-bit integers
  • (Optional) Convert little-endian words to big-endian words

My guess is that it is because a constant value, which is ideal DC, is equivalent to 0 Hz, and that's too low of a frequency for a speaker to produce, so it generates negligible noise instead.

Anyway, I was wondering, how does Audacity generate silence? Is it random number generation in [-7, +7]? Is there a mathematical formula for the noise?

What is the algorithm for producing that "silence", as a list of 16-bit integers? (which I can easily convert into a WAVE file)

Summary:

  • What algorithm does Audacity use / can I use to generate "silence"?
$\endgroup$
10
  • 7
    $\begingroup$ There is this (since 1990) commonly-used technique of dithering but that seems to be a little intense. I would not expect dithering to be toggling the bottom 4 bits (which is what going from -7 to +7 is). I would expect the bottom 2 bits to be toggling. Like going from -1 to +1 with a few 0's in between. $\endgroup$ Feb 18, 2023 at 17:40
  • 1
    $\begingroup$ Well, now we know what the Sound of Silence looks like, at least. $\endgroup$
    – TimWescott
    Feb 18, 2023 at 19:44
  • 4
    $\begingroup$ How did you "generate silence"? Did you, perchance, record a second of input from an unplugged microphone jack or some such? $\endgroup$
    – TimWescott
    Feb 18, 2023 at 19:53
  • 3
    $\begingroup$ Yeah, happens for me too. I don't see a reason why it needs to happen, considering floats can represent 0 exactly. And the same happens even if I create the track at 16-bit PCM in Audacity. When I export as 32-bit float RAW, it gets all zeros though. Related manual section. $\endgroup$
    – jpa
    Feb 18, 2023 at 20:38
  • 2
    $\begingroup$ Audacity works internally with 32-bit floats. When you create silence it creates float zeros. What you see happens when you export the file to wave format. It applies "dithering" to decorrelate the quantization noise from the actual signal. See manual.audacityteam.org/man/dither.html $\endgroup$
    – Hilmar
    Feb 18, 2023 at 20:44

2 Answers 2

19
$\begingroup$

Full silence is just zeroes.

You likely generated the silence to an audio track which is in some other format than 16-bit PCM, like float or 24-bit or 32-bit PCM.

When you exported it as 16-bit wave file, the values need to be converted or truncated to 16-bits. That process may include dithering, so you likely have dithering enabled for conversions in the settings.

Either change the dithering settings, or use 16-bit format for the audio track.

So silence algorithm is not the problem here that would generate random noise, it's the dithering process used in conversions between formats.

$\endgroup$
2
  • $\begingroup$ So, essentially, my manually generated silence can just be zeroes because I don't have to worry about dithering since I'm working only with 16-bit values? $\endgroup$ Feb 20, 2023 at 21:01
  • $\begingroup$ The generated values are likely zero, but they don't get exported as zeroes due to dithering done before export. If you expect and want zeroes, turn off dithering. But in practice, the dithered silence is better, because you at least get some data that's non-zero you can assume as PCM, so many audio DSPs are happier with that, because just having completely flat signal of "Zero PCM" means you can't expect that to be PCM and play it on speakers, if suddenly some bitstream audio appears (like on DVD, Bluray). $\endgroup$
    – Justme
    Feb 20, 2023 at 21:15
5
$\begingroup$

What algorithm does Audacity use / can I use to generate "silence"?

Insert zeros in the audio stream.

However:

Microsoft WAV (the typical format for files ending in .wav) is still a container format; so, what you think you were looking at (16 bit PCM samples) probably wasn't what you're actually looking at. The format is way more complex than what you'll find in books from 1993.

However, in your case, as Justme says: this is just (unnecessary) dithering happening.

What is the algorithm for producing that "silence", as a list of 16-bit integers? (which I can easily convert into a WAVE file)

Generate zeros and save them using your preferred export tool for wave files. It would seem you're already doing that!

So, let's rephrase this to

Knowing I just need to encapsulate zeros in a Microsoft WAV-compatible file, how do I do that?

Many approaches, because many tools and programming languages support writing to WAV files, and any reasonable language will support "vectors of zeros" in some form. But we can do it the very lazy Python way. If you haven't used python before: Paste this in a text file, save the text file (say, as generatesilence.py), go to the directory of that file, and run it (e.g., as python3 generatesilence.py)

#!/usr/bin/env python3
import wave

# Open a (new if necessary) wave file for binary writing
outf = wave.open("silence.wav", "wb")

framerate = 48000 # or whatever you prefer
silenceduration = 60 # or how many seconds you want to produce
bytesperframe = 2 # 2 -> 16 bit

outf.setframerate(48000)
outf.setnchannels(1)
outf.setnframes(int(silenceduration * framerate))
outf.setsampwidth(bytesperframe)

outf.writeframes(
    bytes(
        0 for i in range(int(silenceduration * framerate) * bytesperframe)
    )
)

Note: from a developer's perspective, I'm almost certain you're planning to use this silence in some other system that reads a fixed set of audio formats. Really check whether you really want to use uncompressed PCM audio for that – feels like a huge waste of space (and speed, because compressed audio can typically decoded at a higher rate than your storage can read uncompressed audio). Many programs do just use a more versatile library (like libsndfile) for reading audio files and thus support all the modes of that, not just "1991-style Microsoft WAV", or "later-Windows Microsoft WAV" which can also contain compressed (but not variable-bitrate, so only lossy compression is possible) audio.

$\endgroup$
11
  • $\begingroup$ The process is correct; there is just dithering enabled by default so it does not end up as zeroes on the file. $\endgroup$
    – Justme
    Feb 18, 2023 at 11:16
  • $\begingroup$ yeah, that seems to be the case. $\endgroup$ Feb 18, 2023 at 11:20
  • 1
    $\begingroup$ @Justme you're right, should have actually addressed the concern of OP; fixed that $\endgroup$ Feb 18, 2023 at 11:33
  • 1
    $\begingroup$ The wave format as everyone uses it is not that complex. It is as simple as you'll find in books from 1993. In particular, there are no extra bytes in the middle of the audio data. $\endgroup$
    – user253751
    Feb 19, 2023 at 21:00
  • $\begingroup$ @user253751 personal experience tells me that the "simple" WAV interfaces Matlab and scipy.io already don't agree in a lot of cases, and that the code that was used in GNU Radio prior to release 3.9, which was really based on the win3.11 era WAV format specification, couldn't deal with many .WAV files that you actually encounter in the wild. So, my experience is different to yours! $\endgroup$ Feb 19, 2023 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.