Replies: 3 comments 2 replies
-
Interesting use case! I'm not so sure PWM is good enough quality for anything as "pro-level" as you're thinking of. There's no oversampling, and at 48khz I think there's only ~10bits of precision available (due to PWM hardware frequency limitations). Anyway, there may be a limitation in the PWM hardware module with respect to DMA requests, or I may be miscalculating some internal HW slice addresses. The PWM HW is kind of non-orthogonal due to being built of only 8 slices for ~30 IOs. I'll take a look at the datasheet and see. FWIW, yhe AudioBufferManager has all of its own state inside the instantiated object, so there's no bottleneck there that I can see. |
Beta Was this translation helpful? Give feedback.
-
Thanks Earle I think there is a small bug in your playStereo example. And then i got a full sine wave on the oscilliscope. |
Beta Was this translation helpful? Give feedback.
-
ok, i think i have created a PR. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
The new PWMAudio/AudioBufferManager libraries look very interesting and the 2 examples work great. Well done Earle.
The documentation suggested that i could create multiple PWMAudio devices so I tried to make 2 Stereo devices using the PlayStereo example. One device on pins 0,1 and one device on pins 2,3.
I basically just duplicated the relevant calls to the PWMAudio lib that were in PlayStereo.
The result was that i only got audio out of one set of pins. Whichever set I started last with the begin() call.
I tried a few things like dropping the sample rate to 32000, trying with and without larger buffers, even overclocking and trying different pin combinations with varying degrees of success. The best i did was with low sample rate and overclocking. In that case i got sound out of both sets of pins but the set i started first sounded bit crushed or had extra harmonics added.
I want to get this working so that i can try to make 4 (or event better 8) wavetable oscillator voices for a eurorack module from 2 or 4 stereo PWMAudio devices. At the moment it works great with 2 voices (1 stereo device) but no more.
I feel like i have done something wrong in setting this up.
What is the correct way to setup multiple PWMAudio devices?
My patched version of the .PlayStereo looks like this
/*
This example plays a tune that alternates between left and right channels using a simple sine wave.
Released to the public domain by Earle F. Philhower, III earlephilhower@yahoo.com
*/
#include <PWMAudio.h>
PWMAudio pwm(0, true); // GP0 = left, GP1 = right
//add 2nd device
PWMAudio pwm1(2, true); // GP2 = left, GP3 = right
const int freq = 48000; // Output frequency for PWM
int16_t al = 0;
int16_t ar = 0;
const int notes[] = { 784, 880, 698, 349, 523 };
const int dly[] = { 400, 500, 700, 500, 1000 };
const int noteCnt = sizeof(notes) / sizeof(notes[0]);
int freqL = 1;
int freqR = 1;
double sineTable[128]; // Precompute sine wave in 128 steps
unsigned int cnt = 0;
//add 2nd counter
unsigned int cnt1 = 0;
void cb() {
while (pwm.availableForWrite()) {
double now = ((double)cnt) / (double)freq;
int fl = freqL << 7; // Prescale by 128 to avoid FP math later on
int fr = freqR << 7; // Prescale by 128 to avoid FP math later on
pwm.write((uint16_t)(al * sineTable[(int)(now * fl) & 127]));
pwm.write((uint16_t)(ar * sineTable[(int)(now * fr) & 127]));
cnt++;
}
}
//add 2nd callback
void cb1() {
while (pwm1.availableForWrite()) {
double now = ((double)cnt1) / (double)freq;
int fl = freqL << 7; // Prescale by 128 to avoid FP math later on
int fr = freqR << 7; // Prescale by 128 to avoid FP math later on
pwm1.write((uint16_t)(al * sineTable[(int)(now * fl) & 127]));
pwm1.write((uint16_t)(ar * sineTable[(int)(now * fr) & 127]));
cnt1++;
}
}
void setup() {
// Set up sine table for waveform generation
for (int i = 0; i < 128; i++) {
sineTable[i] = sin(i * 2.0 * 3.14159 / 128.0);
}
pwm.setBuffers(4, 32); // Give larger buffers since we're are 48khz sample rate
pwm.onTransmit(cb);
pwm.begin(freq);
//init 2nd device
pwm1.setBuffers(4, 32); // Give larger buffers since we're are 48khz sample rate
pwm1.onTransmit(cb1);
pwm1.begin(freq);
}
void loop() {
delay(1000);
// Send it out on the LHS
ar = 0;
for (int i = 0; i < noteCnt; i++) {
freqL = notes[i];
al = 5000;
delay(dly[i]);
}
al = 0;
delay(1000);
// Hear reply on RHS
for (int i = 0; i < noteCnt; i++) {
freqR = notes[i] / 4;
ar = 15000;
delay(dly[i]);
}
ar = 0;
delay(3000);
}
Beta Was this translation helpful? Give feedback.
All reactions