jason11892
New member
Intro:
I'm relatively new to both programming and teensy, and I've been trying to make an oscillator whose waveform shape is controlled kind of like an envelope: with attack, hold, and release parameters being controlled in real time. So far, I've been using an arbitrary waveform in waveformMod (I want to do FM later) with the waveform shape controlled by an array. The points of the array are calculated with conditions and math in a for loop. At first, I coded the full oscillator as I wanted it. It outputted sound and was able to be controlled by the potentiometers, but the teensy would stop completely (USB audio, DAC audio, and serial communication) if the total of the knobs reached a certain point. After some searching, I found the problem: this part of the code
should have been
(see the full code below, you can change it back to what it was previously to see the earlier issue). Without the issue solved, if the total of the outputs was high enough, it would automatically output silence based on the if statement. With it fixed, though, it now outputs no sound. Then, I made a simple proof-of-concept sketch to see if what I'm trying to do is even possible, and it doesn't output sound either.
Question:
Is it even possible to have a variable array for an arbitrary waveform? My proof-of-concept sketch leads me to think no, but before I fixed the previous version I was getting a variable oscillator. Maybe my OSC_SCALE and OSC_OFFSET constants are inaccurate? I thought about making separate arrays for each knob position and just choosing one based on knob positions, but that seems unnecessarily clunky. What method would you suggest to achieve a variable oscillator/waveform?
Info:
I'm using a Teensy 3.2 and the Teensy Audio Library for this project. The Teensy is set to Audio + Midi + Serial communication, and I have 3 potentiometers going into A0, A1, and A2, respectively. I also have an audio port wired to the DAC, but I've been mainly monitoring audio via USB (I wrote a simple program to take the teensy audio and output it to my headphones. If you're going to monitor via the DAC, I recommend tuning the volume of the oscillator (AhrOsc.begin) way down, like to 0.01).
Code:
AHR Oscillator:
Proof-of-concept:
Thanks so much! I'm open to learning a new method to achieve what I want, too.
I'm relatively new to both programming and teensy, and I've been trying to make an oscillator whose waveform shape is controlled kind of like an envelope: with attack, hold, and release parameters being controlled in real time. So far, I've been using an arbitrary waveform in waveformMod (I want to do FM later) with the waveform shape controlled by an array. The points of the array are calculated with conditions and math in a for loop. At first, I coded the full oscillator as I wanted it. It outputted sound and was able to be controlled by the potentiometers, but the teensy would stop completely (USB audio, DAC audio, and serial communication) if the total of the knobs reached a certain point. After some searching, I found the problem: this part of the code
Code:
if ((i <= aKnob1 + hKnob1 + rKnob1) && i <= 256) {
Code:
if ((i >= aKnob1 + hKnob1 + rKnob1) && i <= 256) {
Question:
Is it even possible to have a variable array for an arbitrary waveform? My proof-of-concept sketch leads me to think no, but before I fixed the previous version I was getting a variable oscillator. Maybe my OSC_SCALE and OSC_OFFSET constants are inaccurate? I thought about making separate arrays for each knob position and just choosing one based on knob positions, but that seems unnecessarily clunky. What method would you suggest to achieve a variable oscillator/waveform?
Info:
I'm using a Teensy 3.2 and the Teensy Audio Library for this project. The Teensy is set to Audio + Midi + Serial communication, and I have 3 potentiometers going into A0, A1, and A2, respectively. I also have an audio port wired to the DAC, but I've been mainly monitoring audio via USB (I wrote a simple program to take the teensy audio and output it to my headphones. If you're going to monitor via the DAC, I recommend tuning the volume of the oscillator (AhrOsc.begin) way down, like to 0.01).
Code:
AHR Oscillator:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioSynthWaveformModulated AhrOsc; //xy=57,190
AudioOutputUSB usb1; //xy=414,236
AudioOutputAnalog dac1; //xy=464,159
AudioConnection patchCord1(AhrOsc, dac1);
AudioConnection patchCord2(AhrOsc, 0, usb1, 0);
AudioConnection patchCord3(AhrOsc, 0, usb1, 1);
// GUItool: end automatically generated code
int16_t OscArray[256];
int aKnob1 = 0;
int hKnob1 = 0;
int rKnob1 = 0;
const int OSC_SCALE = 65534;
const int OSC_OFFSET = 32767;
void setup() {
// put your setup code here, to run once:
AhrOsc.begin(0.5, 440, WAVEFORM_ARBITRARY);
AhrOsc.arbitraryWaveform(OscArray, float(20000));
AudioMemory(64);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
aKnob1 = analogRead(A0) / 3.99;
hKnob1 = analogRead(A1) / 3.99;
rKnob1 = analogRead(A2) / 3.99;
Serial.println(aKnob1 + hKnob1 + rKnob1);
for (int i = 0; i <= 256; i++){ //loop to calculate the array
if (i < aKnob1) {
OscArray[i] = ((OSC_SCALE / aKnob1) * i) - OSC_OFFSET; //produces an upwards ramp with it's time/length/slope being controlled by aKnob1
}
if ((aKnob1 <= i) && (i < (aKnob1 + hKnob1))) {
OscArray[i] = int(OSC_SCALE - OSC_OFFSET); //produces a constant flat line in between the attack and release with a time/length of hKnob1.
}
if (((aKnob1 + hKnob1) <= i) && (i < aKnob1 + hKnob1 + rKnob1)) {
OscArray[i] = ((-1 * ((OSC_SCALE / rKnob1) * i)) + OSC_SCALE) - OSC_OFFSET; //produces a downwards ramp with it's time/length/slpe being controlled y rKnob1
}
if ((i >= aKnob1 + hKnob1 + rKnob1) && i <= 256) { //line where the previous mistake was
OscArray[i] = -1 * (OSC_SCALE - OSC_OFFSET); // provides a condition if all the stages are over, but the array has more space, fill it with the lowest value.
}
}
}
Proof-of-concept:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioSynthWaveformModulated AhrOsc; //xy=57,190
AudioOutputUSB usb1; //xy=414,236
AudioOutputAnalog dac1; //xy=464,159
AudioConnection patchCord1(AhrOsc, dac1);
AudioConnection patchCord2(AhrOsc, 0, usb1, 0);
AudioConnection patchCord3(AhrOsc, 0, usb1, 1);
// GUItool: end automatically generated code
int16_t OscArray[256];
int Width = 0;
const int OSC_SCALE = 65534;
const int OSC_OFFSET = 32767;
void setup() {
// put your setup code here, to run once:
AhrOsc.begin(0.5, 440, WAVEFORM_ARBITRARY);
AhrOsc.arbitraryWaveform(OscArray, float(20000));
AudioMemory(64);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Width = analogRead(A0) / 3.99;
Serial.println(Width);
for (int i = 0; i <= 256; i++){ //loop to calculate the array, simple PW square wave
if (i <= Width){
OscArray[i] = OSC_SCALE - OSC_OFFSET;
}
if (i > Width) {
OscArray[i] = -1 * (OSC_SCALE - OSC_OFFSET);
}
}
}
Thanks so much! I'm open to learning a new method to achieve what I want, too.