From 461987befe7d3224187a8baad45687cec57e77b2 Mon Sep 17 00:00:00 2001 From: boblark Date: Mon, 27 Feb 2023 12:00:51 -0800 Subject: [PATCH] Major addition of functions from J. Oakley per I16 library. Thanks! --- examples/PlayQueueDemo/PlayQueueDemo.ino | 172 +++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 examples/PlayQueueDemo/PlayQueueDemo.ino diff --git a/examples/PlayQueueDemo/PlayQueueDemo.ino b/examples/PlayQueueDemo/PlayQueueDemo.ino new file mode 100644 index 0000000..8713dfe --- /dev/null +++ b/examples/PlayQueueDemo/PlayQueueDemo.ino @@ -0,0 +1,172 @@ +/* I16 EXAMPLE CONVERTED TO F32 + * A simple queue test which generates a sine wave in the + * application and sends it to headphone jack. The results + * should always be a glitch-free wave, but various options + * can be changed to modify the usage of audio blocks, and an + * ability to execute the loop() function more slowly, with + * simple waveform generation, or more efficiently / faster, + * but requring some programmer effort to re-try if sending + * waveform data fails due to a lack of buffer or queue space. + * + * This example code is in the public domain. + * + * Jonathan Oakley, November 2021 + * Converted from I16 to F32 - Bob Larkin Feb 2023. Thanks, Jonathan + */ + +#include "OpenAudio_ArduinoLibrary.h" +#include "AudioStream_F32.h" +#include "Arduino.h" +#include "play_queue_f32.h" + +AudioPlayQueue_F32 queue1; //xy=917,329 +AudioOutputI2S_F32 i2s2; //xy=1121,330 +AudioConnection_F32 patchCord1(queue1, 0, i2s2, 0); +AudioConnection_F32 patchCord2(queue1, 0, i2s2, 1); +AudioControlSGTL5000 sgtl5000_1; //xy=1131,379 + +#define COUNT_OF(a) (sizeof a / sizeof a[0]) +uint32_t next; + +// ************ SETUP() ************** +void setup() { + pinMode(13,OUTPUT); + + Serial.begin(115200); + delay(1000); + Serial.println("AudioPlayQueue_F32 Test"); + + if (CrashReport) + { + Serial.println(CrashReport); + CrashReport.clear(); + } + + AudioMemory_F32(100); + + sgtl5000_1.enable(); + sgtl5000_1.volume(0.5); + + next = millis(); + + // Comment the following out (or set to ORIGINAL) for old stall behaviour; + // set to NON_STALLING for return with status if audio blocks not available, + // or no room in queue for another audio block. + queue1.setBehaviour(AudioPlayQueue_F32::NON_STALLING); + //queue1.setBehaviour(AudioPlayQueue_F32::ORIGINAL); + queue1.setMaxBuffers(4); +} + +/* + * Generate one sample of a waveform. + * Currently 220Hz sine wave, but could make it more complex. + */ +uint32_t genLen; + +float32_t nextSample() +{ + static float phas = 0.0f; + float32_t amp = 0.05f; + float32_t result = amp*sinf(phas); + genLen++; + + phas += 220./AUDIO_SAMPLE_RATE_EXACT*TWO_PI; + if (phas > TWO_PI) + phas -= TWO_PI; + return result; +} + +int loops; +int nulls,nulls2; +int testMode = 2; // 1: getBuffer / playBuffer; 2: play(), mix of samples and buffers +int playMode; // 1: generate individual samples and send; 2: generate buffer of samples and send +float32_t samples[512],*sptr; // space for samples when using play() +uint32_t len; // number of buffered samples (remaining) + +void loop() { + + switch (testMode) + { + case 1: // use getBuffer / playBuffer + { + float32_t* buf = queue1.getBuffer(); + + if (NULL == buf) + nulls++; + else + { + for (int i=0;i 0) + { + if (0 == queue1.play(samples[0])) // sent a sample... + { + len--; // count down + if (len > 0) // if more to send... + samples[0] = nextSample(); // ...create the next one + } + else + { + nulls++; // count up the re-tries + break; + } + } + break; + + case 2: // send a block of samples + if (0 == len) + { + len = random(10,COUNT_OF(samples)); // be deliberately awkward + for (unsigned int i=0;i 0) // not everything went + { + sptr += len - left; // advance the pointer + nulls2++; // count up the re-tries + } + len = left; + } + break; + } + } + break; + } + + loops++; + if (millis() > next) + { + next += 100; // aim to output every 100ms + + // In NON_STALLING mode this loops really fast, and the millis() value goes up by + // 100 on every output line. In ORIGINAL mode the loop is slow, and the internal + // stall results in slightly unpredictable timestamps. + Serial.printf("%d: millis = %d, loops = %d, nulls = %u, nulls2 = %u, samples = %u\n", + playMode,millis(),loops,nulls,nulls2,genLen); + } +}