Losing COM Serial Port when adding StreamAudio object

Status
Not open for further replies.

alfa66

Well-known member
When I add a StreamAudio object I lose the COM port.
I thought that the teensy was fried and almost tossed it...
I first wrote a small example using the same technique (I am not a C++ wizard, and never thought about writing my own Audiostream object...) and it works fine, so there must be something else that I am doing wrong.


I compile with USB Type: Serial+Audio+Midi

This is my class definition
Code:
include <Arduino.h>
#include "bus.h"
#include "AudioStream.h"
#include "arm_math.h"

class Q : public AudioStream
{
  public:
    Q(void) : AudioStream (2, outputQueueArray) { }   
    virtual void update(void);
    void begin(void);
private:
  audio_block_t *outputQueueArray[2];
};

My understanding is that this way I create a class with two output queues.

This is the definition of the Object in the program:
#include <Audio.h>
#include <Wire.h>
Q *Qchip;

Q                                 DOC_output;         // Queue for DOC
AudioOutputPT8211        pt8211_1;       
AudioConnection          patchCord1(DOC_output, 0, pt8211_1, 0); 
AudioConnection          patchCord2(DOC_output, 1, pt8211_1, 1);  

void doc_init() {

    Qchip = new Q(); 
    AudioMemory(64);  // reserve some Teensy mem for audio purposes...
...
}

void Q::update (void) { //sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) {
...
}
If I remove the class and I just compile with
void audio_update () { //sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) {

}

then I have no issues with loading the sketch in Teensy 4.1.

Any ideas?
Thanks much!

(The code is here
https://github.com/alfa95139/AlfaSoniQMirage/tree/teensy_41_with_emulator
check doc5503.cpp and doc5503.h)
 
Last edited by a moderator:
If you followed the forum rule, we might have solved this already. One thing to watch out for is correct block handling
in the update() method, always checking for NULL blocks and releasing each (non-NULL) block after use.
 
Maybe initialize your pointer, so it can't be NULL at startup. So change this:

Code:
Q *Qchip;

Q                                 DOC_output;         // Queue for DOC

to something like this:

Code:
Q                                 DOC_output;         // Queue for DOC

Q *Qchip = &DOC_output;


About this, which was inside your code:

My understanding is that this way I create a class with two output queues.

Umm, nope. Look at the many existing objects in the library. Only the objects with input ports which receive audio from elsewhere in the library use those. They are for receiving audio blocks. They're not used for transmitting blocks to other library objects, as the code fragment you gave us seems to show.


And yeah, we have the Forum Rule about posting a complete program because it lets us help you better and saves everyone a lot of time.
 
Hi guys, first off - I am very thankful for all the help.
I was hoping that posting the GitHub link to my code was going to be enough - clearly I was wrong and I will change my behavior.

Unfortunately, since the last post, I did not solve ALL the problems that I have with the code that I am working on (which is the emulation of a DSP of one of the synths from the '80s).

But I did eliminate an annoying buzz.
I thought about sharing this because, if implemented, this could be a small enhancement to synth_waveform.cpp .

When I started using the example pt8211sine.ino, i noticed that - unless I select an amplitude different than 0 - the output is an annoying buzz.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>


// GUItool: begin automatically generated code
AudioSynthWaveform waveform1;
AudioOutputPT8211 pt8211_1; //xy=303,78
AudioConnection patchCord1(waveform1, 0, pt8211_1, 0);
AudioConnection patchCord2(waveform1, 0, pt8211_1, 1);
// GUItool: end automatically generated code

void setup() {
AudioMemory(15);
waveform1.begin(WAVEFORM_SINE);
waveform1.frequency(220);
waveform1.amplitude(0.0);
}

void loop() {
}

I did a bit of digging and realized that this can be fixed by making a couple of changes in synth_waveform.cpp

After modifying the *.ino:

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include "mysynthwav.h"


MYSYNTHWAV waveform1;
//AudioSynthWaveform waveform1;
AudioOutputPT8211 pt8211_1; //xy=303,78
AudioConnection patchCord1(waveform1, 0, pt8211_1, 0);
AudioConnection patchCord2(waveform1, 0, pt8211_1, 1);
// GUItool: end automatically generated code

void setup() {
AudioMemory(15);
waveform1.begin(WAVEFORM_SINE);
waveform1.frequency(220);
waveform1.amplitude(0.0);
}

void loop() {
}

I went ahead and created my stripped-down version of synth_waveform.cpp (mysynthwav.h is basically identical to synth_waveform.h, i just changed the name of AudioSynthWaveform to MYSYNTHWAV).


void MYSYNTHWAV::update(void)
{
audio_block_t *block;
int16_t *bp, *end;
int32_t val1, val2;
int16_t magnitude15;
uint32_t i, ph, index, index2, scale;
const uint32_t inc = phase_increment;

ph = phase_accumulator + phase_offset;

/*
if (magnitude == 0) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
return;
}
block = allocate();
if (!block) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
return;
}
*/

block = allocate();

if (!block) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
return;
}

bp = block->data;

if (magnitude == 0) {
phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;

for(i=0; i<AUDIO_BLOCK_SAMPLES; i++) *bp++ = 0;
transmit(block, 0);
release(block);
return;
}

for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
index = ph >> 24;
val1 = AudioWaveformSine[index];
val2 = AudioWaveformSine[index+1];
scale = (ph >> 8) & 0xFFFF;
val2 *= scale;
val1 *= 0x10000 - scale;
*bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
ph += inc;
}

phase_accumulator = ph - phase_offset;

if (tone_offset) {
bp = block->data;
end = bp + AUDIO_BLOCK_SAMPLES;
do {
val1 = *bp;
*bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
} while (bp < end);
}
transmit(block, 0);
release(block);
}

In short:
* I first try to allocate the block.
* If the allocation works, then I look for the magnitude.
* If the magnitude is zero, then I reset the audio buffer before the transmit.
* otherwise move forward as usual...

This way the annoying buzz is eliminated.

Hope this is useful and makes up from my last post!
 
Status
Not open for further replies.
Back
Top