Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Losing COM Serial Port when adding StreamAudio object

  1. #1

    Losing COM Serial Port when adding StreamAudio object

    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/AlfaSon..._with_emulator
    check doc5503.cpp and doc5503.h)
    Last edited by Frank B; 01-12-2021 at 08:29 AM. Reason: use code tags

  2. #2
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,282
    Quote Originally Posted by alfa66 View Post
    When I add a StreamAudio object I lose the COM port.
    This happens when the program crashes.
    Try to reduce your program until it does not crash anymore.

  3. #3
    Senior Member
    Join Date
    Jul 2020
    Posts
    977
    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.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,096
    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.

  5. #5
    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!

Posting Permissions

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