Sinewave synth, modulated output

Status
Not open for further replies.
Here's the code, stripped down to the bare bones, running on Teensy 3.2 with the Audio Shield:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>

AudioSynthWaveformSineHires sine_hires1;
AudioOutputI2S           i2s1;
AudioConnection          patchCord1(sine_hires1, 0, i2s1, 0);
AudioConnection          patchCord2(sine_hires1, 1, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;

void setup() {
  AudioMemory(20);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.8);
  sine_hires1.amplitude(0.9);
  sine_hires1.frequency(20000);
}

void loop() {
}

Here's the output, just one scope sweep, cellphone picture of ancient and venerable scope:

scope.jpg

I'm seeing a modulation of the sinewave, don't know if this is an expected artifact, or something wrong.
 
The short answer is yes, the artifacts you are seeing are expected. It's called aliasing.

It appears you are trying to generate a 20kHz sine wave, while the audio board outputs at a 44.1kHz sampling rate. The frequency of the sine wave is high enough that not enough samples exist to reliably capture the proper peaks and accurately represent it. In this specific case, there are approximately 2 samples per cycle, and their offset from the peaks will drift, causing the apparent modulation.

There is a lot to say on the subject of aliasing, and it's covered pretty thoroughly in several places on the web, so I won't go in to detail. Instead I'll just say that the main thing to know is that your sampling rate needs to be several times higher than the frequency you are attempting to reproduce.

Side note: 20kHz is at the upper range of human hearing, with many humans unable to hear it, and those that can hear it would often consider it painful.
 
It does look like aliasing, but I'm surprised because I thought that a codec with oversampling should be able to substantially eliminate aliasing of signals that are below the Nyquist limit. The datasheet for the codec doesn't give any guidance in that regard.

Don't worry about 20 kHz. I'm too old to hear it, plus I'm not planning on feeding the signal through speakers. This is for a fiendish experiment, and I didn't expect what I was seeing, so I boiled the code down to its bare essentials to post here.

Post 34 at this link, from our fearless leader, suggests that the SGTL5000 is oversampled: https://forum.arduino.cc/index.php?topic=358314.30
 
I don't believe that is what is meant by aliasing in the usual usage. Nyquist Shannon theorem says the information from a waveform whose bandwidth is less than 0.5 SR can be perfectly captured and the original reproduced from the sample data. Anything above 0.5 SR cannot be captured as the frequency content cannot (theoretically and not just in practice) be distinguished from aliases within the bandwidth of the SR.

Failure to reproduce sub Nyquist signals isn't aliasing...

Caveat..not an engineer.
 
Last edited:
Amusingly, I had to dig into this. This graph shows two sinusoids, 20 and 24.1 kHz, in a 9:1 amplitude ratio. It does a pretty good job of simulating the measured waveform:

alias.jpg
 
It is definitely aliasing, and it's not the fault of the codec. The aliasing is occurring during the initial synthesis.

To show what is going on, I generated a 20kHz sine wave at 44.1kHz sampling rate in audacity:

20161129_22-44-49.png

The top waveform is the 20kHz sine wave at 44.1kHz, and shows how the waveform is aliased due to sampling rate. This is essentially the same signal that will be generated by sine_hires1 in your code. The bottom waveform is a 20kHz sine wave but at 10x the sampling rate, which is not noticeably aliased and demonstrates your expected waveform.

You may wonder why this looks worse than your output. Audacity is using basic linear interpolation for displaying the waveform, which does nothing to compensate for aliasing. Your output is going through some filtering, possibly some intentional filtering by the codec, but in the least some filtering caused by how the analog circuitry works.

If I bring the original 20kHz @ 44.1kHz wave in to Audition and let it use some better interpolation to reconstruct the wave at a higher sampling rate, in a much more similar way to how the codec/DAC would, it results in the following waveform:

20161129_22-54-58.png

Audition is quite good at this actually, but you can see it results in the same type of artifacts as you are capturing on your scope.

The Nyquest Theorem does not guarantee that any frequency below the nyquest frequency (half the samplerate) will be perfectly represented; that is a misinterpretation. It's better thought of in the reverse: frequencies above the nyquest frequency will not be preserved.

Frequencies below the nyquest frequency may not be perfectly represented, but (depending on bandwidth of the signal) should be reproduced well enough to be reasonably reconstructed with some filtering.
 
Last edited:
...The Nyquest Theorem does not guarantee that any frequency below the nyquest frequency (half the samplerate) will be perfectly represented...
I agree except with calling it aliasing as aliasing happens above Nyquist and is a theoretically necessary outcome and not a limitation of interpolation.
 
Status
Not open for further replies.
Back
Top