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

Thread: Problems With Coding My First Teensy 4.0 Sawtooth Synth

  1. #1
    Junior Member
    Join Date
    Jun 2020
    Posts
    10

    Problems With Coding My First Teensy 4.0 Sawtooth Synth

    Hey guys,

    first of all I'm sorry if I'm posting this thread into the wrong forum section!



    I got a problem with my Arduino code as you can see below in the pictures (here again I'm sorry if making a screenshot was inappropriate, not sure how to show you the whole thing otherwise).

    I started off with one of the Teensy example audio projects inside Arduino and tried to implement my own code, but failed so far

    My idea was to start with a simple sawtooth oscillator and to try to create a modulo counter which should write the incremented values into my audio block pointer as you can see below.

    Does anyone know what my mistake is so far? I tried to debug with serial.print() (you can see the serial monitor in the last picture). Why is the wrap around coming between 18000 and 19000 - and not 32767 like i wanted it to?

    At the moment I'm just hearing a flimsy roar at a high frequency on my speakers (much higher than the wanted 100 Hz) so my code is clearly not working at all


    Click image for larger version. 

Name:	unnamed.png 
Views:	23 
Size:	81.6 KB 
ID:	21146


    Click image for larger version. 

Name:	unnamed-1.png 
Views:	35 
Size:	85.2 KB 
ID:	21147


    Click image for larger version. 

Name:	unnamed-2.png 
Views:	13 
Size:	81.4 KB 
ID:	21148


    Click image for larger version. 

Name:	unnamed-3.png 
Views:	12 
Size:	83.1 KB 
ID:	21149


    Click image for larger version. 

Name:	unnamed-4.png 
Views:	13 
Size:	101.5 KB 
ID:	21150



    Hope you guys can help me!

    with best wishes,
    MarkV

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    350
    Post code as code using the # button, not as images please.

  3. #3
    Senior Member
    Join Date
    Jul 2020
    Posts
    350
    You need to post your code in a usable format if you want help. Images are not usable for code, or text, since they cannot be
    put into a text editor.

  4. #4
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Quote Originally Posted by MarkT View Post
    You need to post your code in a usable format if you want help. Images are not usable for code, or text, since they cannot be
    put into a text editor.
    Hey MarkT, thanks for your comments so far. I thought the code on every file is important so I sent you images of the files, but i can start with the most important lines of code first and see if those work at least!

    Code:
    blockpointer = block -> data;
    *blockpointer = 0;
    
    for (i=0; i<AUDIO_BLOCK_SAMPLES; i++) {
            if (*blockpointer > 32766)
              {*blockpointer = -32767;}
                *blockpointer += inc;
    }
    This code is supposed to create a simple sawtooth waveform. I hear a flimsy bleep on my speakers but I neither can change the frequency of the output signal, nor can I say for sure that the signal is sawtooth-shaped...

    Anyone spotting my mistake(s) so far?

  5. #5
    Senior Member
    Join Date
    Jul 2020
    Posts
    350
    Clearly can't be correct, simple to see why if you analyze what happens for both cases. One defines the sample,
    the other alters what's there already there (junk presumably since a waveform generator will be calling allocate() for
    its blocks).

    But without the whole code this is basically guesswork. Perhaps take note of the forum rules this time? Complete code to
    reproduce the issue. Problems are fixed by reproducing them, not just looking at code, but running it and debugging.

  6. #6
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Quote Originally Posted by MarkT View Post
    Clearly can't be correct, simple to see why if you analyze what happens for both cases. One defines the sample,
    the other alters what's there already there (junk presumably since a waveform generator will be calling allocate() for
    its blocks).

    But without the whole code this is basically guesswork. Perhaps take note of the forum rules this time? Complete code to
    reproduce the issue. Problems are fixed by reproducing them, not just looking at code, but running it and debugging.
    Dear MarkT,
    sorry but I just don't really understand what You are trying to tell me with the first paragraph of Your answer.

    In terms of Your second paragraph: I don't really get the issue here You are having with my thread (since I'm a Newbie maybe). Am I supposed to send every single line of my code (from every attached .h or .cpp file) with the forums #-command? I can do that if you wish ... but I've sent 5 pictures with my complete project to this thread... if You wanna have a closer look on the whole thing and are interested - why not check out the images? I could of course completely copy and paste all my lines of code into the #-command but since no one but you showed any interest, i don't really see where this is going...

    All I'm trying to implement here is a oscillator programmed by myself (sawtooth right now, but any other waveform would do the job as well).
    I read about projects here on this forum most of the time, where the teensy sawtooth is used from the teensy library (something like "play sawtooth"), but I want to program the oscillator waveforms by myself, has anyone some experience with that and could share it with me?

  7. #7
    Senior Member
    Join Date
    Jul 2020
    Posts
    350
    A waveform generator should be overwriting the buffer with generated samples. Your code sometimes overwrites a sample,
    but often just modifies the sample, despite the original contents being undefined. AFAICT. You are using += which only
    modifies.

    Dry run the code if you don't believe me.

  8. #8
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    277
    Quote Originally Posted by MarkV View Post
    In terms of Your second paragraph: I don't really get the issue here You are having with my thread (since I'm a Newbie maybe). Am I supposed to send every single line of my code (from every attached .h or .cpp file) with the forums #-command? I can do that if you wish ... but I've sent 5 pictures with my complete project to this thread... if You wanna have a closer look on the whole thing and are interested - why not check out the images? I could of course completely copy and paste all my lines of code into the #-command but since no one but you showed any interest, i don't really see where this is going...
    Hi MarkV,
    What MarkT is meaning that if you post the complete code, either by using the # command or by zipping & attaching your project folder, it is way more inviting for other forum people to look into your code. And thus generate interest!
    To be honest, if I see code in images, I usually skip because I'm not going to type all the displayed code into the Arduino editor in order to compile, run and debug.
    You may feel uncomfortable sending all your code but please be assured that in this forum we are all here to help and to learn & teach, not to judge your software writing skills.

    Paul

  9. #9
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Hey everyone,

    sorry that I didn't write you guys til now, I was on vacation and I'm just now back at my computer at the university and was able to copy the code from there yesterday! here it is:

    FILE1 mulitwaveform synthesizer test
    Code:
    #include <Audio.h>
    #include "AudioAusgang.h"
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Bounce.h>
    AudioAusgang      audio_ausgang;      //xy=171,84
    AudioSynthWaveform       waveform2;      //xy=178,148
    AudioOutputI2S           i2s1;           //xy=360,98
    AudioOutputAnalogStereo  dacs1;          //xy=372,173
    AudioConnection          patchCord1(audio_ausgang, 0, i2s1, 0);
    AudioConnection          patchCord2(audio_ausgang, 0, dacs1, 0);
    AudioConnection          patchCord3(waveform2, 0, i2s1, 1);
    AudioConnection          patchCord4(waveform2, 0, dacs1, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=239,232
    
    void setup() {
     Serial.begin(9600);
     
     AudioMemory(10);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.8); // caution: very loud - use oscilloscope only!
      audio_ausgang.frequency(100.0);
    }
    
    void loop() {
      AudioNoInterrupts();
      AudioInterrupts();
    }






    FILE 2 AudioAusgang.cpp
    Code:
    #include <Arduino.h>
    #include "AudioAusgang.h"
    #include "arm_math.h"
    #include "utility/dspinst.h"
    #define IMPROVE_EXPONENTIAL_ACCURACY
    void AudioAusgang::update(void)
    {
      audio_block_t *block;    
      int16_t *blockpointer, *end;
      int32_t val3=pre_inc;
      int32_t val4=phase_increment;
      uint32_t i, phas;
      const uint32_t inc = phase_increment; 
     
      phas = 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;
      }
      blockpointer = block->data;  
      *blockpointer = 0;
     
      for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {  
       *blockpointer += inc;
        if(*blockpointer>32766)
          {*blockpointer = -32767;}
        
       // *blockpointer++ = signed_multiply_32x16t(magnitude, phas);
      }
      
      transmit(block, 0);
      release(block);
     }





    FILE 3 AudioAusgang.h
    Code:
    #ifndef audio_ausgang_h_
    #define audio_ausgang_h_
    #include <Arduino.h>
    #include "AudioStream.h"
    #include "arm_math.h"
    class AudioAusgang : public AudioStream
    {
    public:
      AudioAusgang(void) : AudioStream(0,NULL)
     {
      }
     void frequency(float frequenz) {
      frequenz = 2*frequenz;
        if (frequenz < 0.0) {
          frequenz = 0.0;
        } else if (frequenz > AUDIO_SAMPLE_RATE_EXACT / 2) {
          frequenz = AUDIO_SAMPLE_RATE_EXACT / 2;
        }
      frequenz = frequenz/2; 
      Periodendauer = 1/frequenz;
      pre_inc = Periodendauer * AUDIO_SAMPLE_RATE_EXACT ;   
      saw_inc = pre_inc / 2;
      phase_increment = 32676 / saw_inc;
      if (phase_increment > 0x7FFE0000u) phase_increment = 0x7FFE0000;        // 0x7FFE0000 (hexadezimal) = 2147352576 (dezimal) 
      }
      virtual void update(void);
    private:
      float Periodendauer;
      float saw_inc;
      float pre_inc;
      uint32_t phase_accumulator=0;
      uint32_t phase_increment;
      uint32_t phase_offset=0;
      int32_t  magnitude = 65536.0;
    };
    #endif


    I checked with Serial.print if the value "inc" is changing correctly due to the current frequency (which is controlled in file 1 frequency) and the values seemed to be okay. However I still think that I made a mistake in the way i handled the audio blocks...
    MarkT pointed out I should not have used += for the block pointer in file 2, but what would be an alternative way?

    Thanks for your help guys!

Posting Permissions

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