dds sine wave frequency changing

Looking at the .wav file with Audacity, I think that the waveform is clipped, and slew-rate-limited. Looks like there's trouble on the analog side. I don't think that you've gotten the project to a point where it will really help much to add a complicated filter on the output. I'd suggest fixing it as best you can before you go to that effort.

Here's what I undestand about your project, based on what you've told us so far:

  • Looking at what I think is your code - from the link you included with your original post - it appears that your output data range from 0 to 254. That corresponds to a time-averaged output voltage ranging from 0 to nearly 5V, or almost full-scale for a 5V system.

  • You're using an RC filter on the output: 330 ohms and 0.01 uF. I presume that the resistor is connected between the output pin and the capacitor, and that the capacitor is connected between the resistor and ground. I also presume that the audio output is taken from the junction of the resistor and the capacitor. That output filter will have a cutoff frequency of about 48 kHz, and it won't noticeably attenuate the frequencies that you're interested in, which range from 440 Hz to about 1.5 kHz - and those figures are based on the code you linked with your first post, rather than the code that you've pasted into your posts. It's worth noting that a this filter won't attenuate the 32 kHz PWM signal very much, either. It's not clear to me that it's doing much good.

  • You're using an LM386 to amplify the output, but you haven't described how it's hooked up. I presume that it's connected to provide a gain of 20, because that configuration uses the fewest parts, and that you're powering it from 5V and ground.

  • You recorded the wav file that you posted using a speaker and microphone, rather than directly connecting the filter output to a recording device. I don't see much of the PWM signal in the file, so I suspect that the whole circuit - including the LM386, the microphone, and the recording input - attenuate that signal quite a lot.

So, it looks like you're using a 5V peak-to-peak signal to drive an amplifier with a gain of 20, and a power supply of 5V. The amplifier can't deliver 20 times the input voltage under those conditions, so the output is clipped.

The LM386 has an input resistance of 50k ohms, so a quick way to get the output signal into the linear range is to connect a 1M ohm resistor between the output of your filter and the input of the LM386. The voltage divider formed by the 1M ohm resistor and the 50k ohm internal impedance of the LM386 will attenuate the input signal by a factor of 20, and the amplifier won't be forced to clip the output signal. You might be better off with a 1.2M ohm resistor. Either way, the impedance of the 1M+ ohm resistor is much higher than the filter's impedance, so it won't affect the filtered output in any noticeable way.

I believe also that you'll get better results if you use an output filter with a lower corner frequency. I'd suggest a frequency of maybe 6 kHz - two octaves up from the highest frequency you'll output, and 2+ octaves below the PWM frequency. As it stands, your output filter passes the PWM frequency almost unaffected. Maybe change the 330 ohm resistor to a 2.5k ohm resistor.

In the wav file, the regions between the flat-tops show a nearly constant slope, but it's too shallow to correspond to a sine signal with the same frequency as the wave in the file. That leads me to believe that the output is also slew-rate limited. The LM386 datasheet doesn't describe a slew rate. However, the data in the wave file are pretty much what I'd expect to see for an overdriven, slew-rate limited amplifier. Reducing the input signal, as described above, will help a lot with the slew rate - it'll reduce the rate by a factor of 20.

Try that, and see if you don't get some improvement. I believe that you'll hear only a small loss of volume, but a much clearer sine output.

I've made a lot of assumptions, and those could be wrong. But, we don't have much information to work with. I'll note, though, that the wav file provides a lot of insight into your system, and we'd have never gotten it from a verbal description of the audio. I'll also note that the audio doesn't sound bad at all, and it sounds to me that it's doing what you wanted it to do. I'd have thought that the effect you describe was an artifact of the recording technique. If I'd built this project, I might be calling it a success by now.