Forum Rule: Always post complete source code & details to reproduce any issue!

# Thread: Alternative sine-wave oscillator object

1. ## Alternative sine-wave oscillator object

Following this paper: https://ccrma.stanford.edu/~jos/pdf/...AndSmith86.pdf

I've created a sine wave generator that should perform as well as the AudioSynthWaveformSineHires object without
nearly so much computation, basically 2 muls-rshifts and 2 add/subs per sample. Perhaps a candidate to replace the
inefficient AudioSynthWaveformSineHires class?

https://github.com/MarkTillotson/Aud..._resonator.cpp
https://github.com/MarkTillotson/Aud...ed_resonator.h

Seems to perform OK, I've made the frequency() setting function phase-continuous, and I think I've tweaked it so overflow
never happens (some of these iterative methods can go slightly above the nominal amplitude at times at the extremes of
frequency).

I did a fair bit of modelling in Python for this and another (single multiply) iteration, and this performed better at low
frequencies.

2. I've just found a paper that includes a summary of seven iterative sinusoid generators in an appendix:

I guess I should investigate some more of them...

3. This is very cool. So you are versed in python and cpp? Your code is amazingly easy to read, good job.

Can I ask: what might you be able to do with this? I'm trying to gain the cpp skills to build this for the teensy, it looks like you might have the skills to do it in an afternoon

4. Originally Posted by boxxofrobots
This is very cool. So you are versed in python and cpp? Your code is amazingly easy to read, good job.
Among others, yes - I try to make code clear so I can understand it down the line - visual formatting is everything for
code clarity and for spotting bugs by eye - lots of whitespace always!
Can I ask: what might you be able to do with this? I'm trying to gain the cpp skills to build this for the teensy, it looks like you might have the skills to do it in an afternoon
Not sure what you mean - there's an image and a wav file there, not a user of JupyterNB myself.

5. OK, let's try this.
Code:
```import numpy as np
import matplotlib.pyplot as plt
from matplotlib.image import imread
import sounddevice as sd
from scipy.signal import correlate
import noise

terrainsize = 256

#load terrain from 256x256 or 512x512 png

#terrain is perlin noise
#perlin noise generator coeffs

freq=1400
octaves=33

for y in range(terrainsize):
for x in range(terrainsize):
zvalues[x][y] = int(noise.snoise2(x / freq, y / freq, octaves) * 32767)

sps = 44100                #sample rate
duration_s = 1#0.0029            #duration of our waveform. .0029 at 44.1k makes 128 entry buffer. Set long as needed
each_sample_number = np.arange(duration_s * sps)

scale_x = terrainsize / 13.1  #this scales the orbit x size
scale_y = terrainsize / 8.1  #scale orbit y size. Changing these vales changes orbit from circular to ellipse

offset_x = 140                 #center of orbit offset x terrain axis
offset_y = 120                 #center of orbit offset y terrain axis

freq_hz = 108.0            #osc freq
fm=1.00
# for this demo, moving these values will aptly demonstrate the wave terrain.
def wavetable(_size): ##122uS per loop on my machine to make geometry calculations on 2900uS buffer frame of audio
wavex = np.sin(2 * np.pi * each_sample_number * freq_hz * fm / sps)
wavey = np.cos(2 * np.pi * each_sample_number * freq_hz * fm / sps)
tablex = np.int16(offset_x + (wavex * scale_x))
tabley = np.int16(offset_y + (wavey * scale_y))
ctablex = np.clip(tablex,0,terrainsize-1)  #clipping to terrainsize takes as long as making the tables
ctabley = np.clip(tabley,0,terrainsize-1)
ctablez = [x for x in range(_size)]
for v in range(0,_size):
ctablez[v] = zvalues[ctablex[v],ctabley[v]]

ctablez = np.int16(ctablez)
return ctablez```
That's code for a wave terrain oscillator. The wav file is the result of playing back a Perlin noise terrain. It uses two oscillators in quadrature to generate an x,y coordinate to read magnitude from a table. This version uses a 256x256 table for 16 bit use. but a terrain oscillator with 65536 x 65536, tracking a plane of coordinates from -(2,147,483,648) to + (2,147,483,647) would give you very good lfo accuracy. Of course, the great thing about it is it makes an excellent oscillator in general. Maybe I'll try to hack your code. I just need to be able to read a 256x256 array, not as easy in c as in python. Nothing is as easy in c as it is in python

6. Originally Posted by boxxofrobots
OK, let's try this.
...

That's code for a wave terrain oscillator. The wav file is the result of playing back a Perlin noise terrain. It uses two oscillators in quadrature to generate an x,y coordinate to read magnitude from a table. This version uses a 256x256 table for 16 bit use. but a terrain oscillator with 65536 x 65536, tracking a plane of coordinates from -(2,147,483,648) to + (2,147,483,647) would give you very good lfo accuracy. Of course, the great thing about it is it makes an excellent oscillator in general. Maybe I'll try to hack your code. I just need to be able to read a 256x256 array, not as easy in c as in python. Nothing is as easy in c as it is in python
Had a quick play with this - it needs interpolation between samples to prevent aliasing for low frequencies I think
- it had the jaggies at 108Hz due to the small orbit size. In other words the map should be bilinearly interpolated
or similar (you'd get that for free in a renderer implementation!). C arrays are just as easy to read as Python surely
- so easy you can read off the end of them even!

I was actually thinking of doing an explicit quadrature oscillator object for the Audio lib as it happens. I found another good
paper on recursive oscillators too, http://www.claysturner.com/dsp/2nd_OSC_paper.pdf

7. Originally Posted by MarkT
I was actually thinking of doing an explicit quadrature oscillator object for the Audio lib as it happens.
And here it is!

8. That will be perfect for building an am radio transceiver in the audio object. Very cool, thanks.

This reminds me: we need a half wave detector as well. The full wave rectifier is not suited as a detector.

9. Originally Posted by MarkT
And here it is!
And I've been looking at the output on my spectrum analyzer today, couldn't see any issues and the main peak has
perhaps a trace of phase noise close-in:

The frequency span is 200Hz, tone at 10kHz

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•