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

Thread: Teensy Audio Library create melody

  1. #1
    Junior Member jcfrgmn's Avatar
    Join Date
    Jun 2016
    Location
    Menlo Park, CA
    Posts
    10

    Teensy Audio Library create melody

    All,

    This is just killing me. I really like the Audio Library and the very cool GUI. With it I can make incredible sounds and the tool set is very rich so I can add reverb, SV filtering, etc.

    I am super embarrassed, but I do not know how to produce a melody of say 3 notes. Using 'delay()' causes artifacts, and the interrupt driven tool set runs right over it. I am not talking about delays at the sample level. What I would like to do is produce three notes, over say, 3 seconds... and I just can not figure out how to do it.

    I have searched, and searched... but using delay in the search pulls up sample delay, but not say 1000 delay so I can produce a sequence of notes. The Monolith code must contain the code, but it is hard to tease it out.

    And I have tried stop and start audio interrupt (or what ever it is called).

    The protocol is to add code so it is included below, but it does not include the multiple note function, but it would be after the main loop detecting a button push where I would play three notes, not one. The place I would like the short sequence is:

    if (buttonDrum1.fallingEdge()) {
    drum1.noteOn();
    }

    - I want to trigger three notes, not one.

    Thanks for any quick references to the forum or other examples.

    I am really stuck.

    Thanks for your kindness,

    John

    ----------------------------------------------------------------------------------------------------------------------


    // sDX_tAD_912 Program for Teensy 3.6 (4.16.17) board to play drums
    // Sept. 12, 2017, stored in db>jcarter>projects>arduino
    // modified from program for Teensy 3.2 (3.6.17) board
    // A2, A3 controls level, depth of drum harmonics
    // flange help from audio>effects>flange
    // chorus help from audio>effects>chorus
    // optimizing with one note, different channels


    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <synth_simple_drum.h>
    #include <Bounce.h> // Pushbutton Debouncer

    // =========================CHORUS=================== ============
    // Number of samples in each delay line
    #define CHORUS_DELAY_LENGTH (16*AUDIO_BLOCK_SAMPLES)
    // Allocate the delay lines for left and right channels
    short l_CH_delayline[CHORUS_DELAY_LENGTH];
    short r_CH_delayline[CHORUS_DELAY_LENGTH];
    // number of "voices" in the chorus which INCLUDES the original voice
    int n_chorus = 2;
    // =========================CHORUS=================== ============

    // ###########################FLANGE################# #############
    #define FLANGE_DELAY_LENGTH (2*AUDIO_BLOCK_SAMPLES) // Was 2
    // Allocate the delay lines for left and right channels
    short l_delayline[FLANGE_DELAY_LENGTH];
    short r_delayline[FLANGE_DELAY_LENGTH];
    int s_idx = 2*FLANGE_DELAY_LENGTH/4;
    int s_depth = FLANGE_DELAY_LENGTH/4;
    double s_freq = 4;
    float fkey = 134.0;
    // ###########################FLANGE################# #############

    // +++++++++++++++++++++++++REVERB+++++++++++++++++++ ++++++++++++
    float rt60 = 1.0;
    // +++++++++++++++++++++++++REVERB+++++++++++++++++++ ++++++++++++

    static uint32_t next;
    int led = 13;



    float f1 = fkey; float f2 = fkey; float f3 = fkey ; float f4 = fkey;

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

    // GUItool: begin automatically generated code
    AudioSynthSimpleDrum drum1; //xy=172,207
    AudioSynthSimpleDrum drum4; //xy=171,482
    AudioSynthSimpleDrum drum3; //xy=173,263
    AudioSynthSimpleDrum drum2; //xy=178,319
    AudioSynthWaveform waveform1; //xy=183,401
    AudioFilterStateVariable filter1; //xy=324,352
    AudioMixer4 mixer2; //xy=476,289
    AudioEffectFlange flange1; //xy=610,208
    AudioEffectReverb reverb1; //xy=613,289
    AudioEffectChorus chorus1; //xy=616,481
    AudioMixer4 mixer1; //xy=856,336
    AudioOutputI2S i2s1; //xy=1001,331
    AudioConnection patchCord1(drum1, flange1);
    AudioConnection patchCord2(drum4, chorus1);
    AudioConnection patchCord3(drum3, 0, mixer2, 0);
    AudioConnection patchCord4(drum2, 0, filter1, 0);
    AudioConnection patchCord5(waveform1, 0, filter1, 1);
    AudioConnection patchCord6(filter1, 0, mixer2, 1);
    AudioConnection patchCord7(filter1, 0, mixer1, 2);
    AudioConnection patchCord8(mixer2, reverb1);
    AudioConnection patchCord9(flange1, 0, mixer1, 0);
    AudioConnection patchCord10(reverb1, 0, mixer1, 1);
    AudioConnection patchCord11(chorus1, 0, mixer1, 3);
    AudioConnection patchCord12(mixer1, 0, i2s1, 0);
    AudioConnection patchCord13(mixer1, 0, i2s1, 1);
    AudioControlSGTL5000 sgtl5000_1; //xy=843,437
    // GUItool: end automatically generated code

    AudioControlSGTL5000 audioShield;

    Bounce buttonDrum1 = Bounce(0, 16); // 16 = 16 ms debounce time
    Bounce buttonDrum2 = Bounce(1, 16);
    Bounce buttonDrum3 = Bounce(2, 16);
    Bounce buttonDrum4 = Bounce(3, 16);

    void setup() {

    pinMode(led, OUTPUT);
    blink (9);
    blink (2);
    //blink (4);

    // ###########################FLANGE################# #############

    // Set up the flange effect:
    // address of delayline
    // total number of samples in the delay line
    // Index (in samples) into the delay line for the added voice
    // Depth of the flange effect
    // frequency of the flange effect
    flange1.begin(l_delayline,FLANGE_DELAY_LENGTH,s_id x,s_depth,s_freq);

    // Initially the effect is off. It is switched on when the
    // PASSTHRU button is pushed.
    flange1.voices(FLANGE_DELAY_PASSTHRU,0,0);
    // ###########################FLANGE################# #############

    // =========================CHORUS=================== ============
    chorus1.begin(l_CH_delayline,CHORUS_DELAY_LENGTH,n _chorus);
    // =========================CHORUS=================== ============

    // +++++++++++++++++++++++++REVERB+++++++++++++++++++ ++++++++++++
    reverb1.reverbTime(rt60);
    // +++++++++++++++++++++++++REVERB+++++++++++++++++++ ++++++++++++

    //*************************SVFilter***************** **************
    filter1.frequency(fkey*2.0);
    filter1.resonance(2);
    filter1.octaveControl(2);
    //*************************SVFilter***************** **************

    //++++++++++++++++++++++++WAVEFORM++++++++++++++++++ ++++++++++++++
    waveform1.begin(0.5, 10.0, WAVEFORM_SINE); // Frequency rate at 10 hz
    //++++++++++++++++++++++++WAVEFORM++++++++++++++++++ ++++++++++++++



    drum1.frequency(f1); //
    drum2.frequency(f2); //
    drum3.frequency(f3); //
    drum4.frequency(f4); //


    // Configure the pushbutton pins
    pinMode(0, INPUT_PULLUP);
    pinMode(1, INPUT_PULLUP);
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);

    Serial.begin(115200);

    // audio library init
    AudioMemory(15);


    audioShield.enable();
    audioShield.volume(0.5);

    next = millis() + 1000;

    AudioNoInterrupts();

    drum1.length(300);
    drum1.secondMix(0.5);
    drum1.pitchMod(0.45);


    drum2.length(300);
    drum2.secondMix(0.5);
    drum2.pitchMod(.50);


    drum3.length(300);
    drum3.secondMix(.5);
    drum3.pitchMod(0.5);

    drum4.length(300);
    drum4.secondMix(0.5);
    drum4.pitchMod(0.55);

    sgtl5000_1.enable();
    sgtl5000_1.volume(0.5);

    mixer1.gain(0,2.);
    mixer1.gain(1,2.);
    mixer1.gain(2,4.0);
    mixer1.gain(3,2.0);
    mixer2.gain(0,1.5);
    mixer2.gain(1, 0.25);

    AudioInterrupts();
    }

    void loop() {
    digitalWrite(led, LOW);
    // ###########################FLANGE################# #############

    flange1.voices(s_idx,s_depth,s_freq);

    // ###########################FLANGE################# #############

    // =========================CHORUS=================== ============

    chorus1.voices(n_chorus);

    // =========================CHORUS=================== ============

    float freqMult = (map(analogRead(A2),0,1023,1000,8000))/1000.0; // 0 - 4.0
    drum1.frequency(fkey*freqMult); //
    drum2.frequency(fkey*freqMult); //
    drum3.frequency(fkey*freqMult); //
    drum4.frequency(fkey*freqMult); //

    rt60 = 5*((map(analogRead(A3),0,1023,0,1000))/1000.0); // 0 - 5.0 seconds
    reverb1.reverbTime(rt60);

    float level = 0.75;
    drum1.secondMix(level);
    drum2.secondMix(level);
    drum3.secondMix(level);
    drum4.secondMix(level);

    float depth = 0.33;
    drum1.pitchMod(depth);
    drum2.pitchMod(depth);
    drum3.pitchMod(depth);
    drum4.pitchMod(depth);

    float length_ms = 2000.0; // length = 500 ms
    length_ms = length_ms/4.0;
    drum1.length(length_ms);
    drum2.length(length_ms);
    drum3.length(length_ms);
    drum4.length(length_ms);

    buttonDrum1.update(); buttonDrum2.update(); buttonDrum3.update(); buttonDrum4.update();
    if (buttonDrum1.fallingEdge()) {
    drum1.noteOn();
    }
    if (buttonDrum2.fallingEdge()) {
    drum2.noteOn();
    }
    if (buttonDrum3.fallingEdge()) {
    freqMult = 4.0;
    drum3.frequency(f2*freqMult); //
    drum3.noteOn();

    }
    if (buttonDrum4.fallingEdge()) {
    drum4.noteOn();
    }
    digitalWrite(led, HIGH);
    }


    // ###########################FLANGE################# #############

    void blink(int number){
    for (int i = 0; i<(number); i++){
    digitalWrite(led, HIGH);
    delay(100);
    digitalWrite(led, LOW);
    delay(100);
    }
    delay(100);
    }
    Last edited by jcfrgmn; 09-21-2017 at 05:39 AM. Reason: add code

  2. #2
    Junior Member jcfrgmn's Avatar
    Join Date
    Jun 2016
    Location
    Menlo Park, CA
    Posts
    10
    I solved my own problem. The solution appears to be to either use delay() or a while loop with millis() as can be seen from the code below. I do think there may be some interaction between the delay() and reverb or flanging, but we shall see. The millis() test should be a good backup. Here is the working code for a 3 note drum melody.

    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <synth_simple_drum.h>
    #include <Bounce.h> // Pushbutton Debouncer

    static uint32_t next; // long unsigned int to hold time value
    int led = 13;
    float fkey = 134.0;

    // GUItool: begin automatically generated code
    AudioSynthSimpleDrum drum1; //xy=172,207
    AudioOutputI2S i2s1; //xy=1001,331
    AudioConnection patchCord1(drum1, 0, i2s1, 0);
    AudioConnection patchCord2(drum1, 0, i2s1, 1);
    AudioControlSGTL5000 sgtl5000_1; //xy=737,488
    // GUItool: end automatically generated code

    AudioControlSGTL5000 audioShield;

    Bounce buttonDrum1 = Bounce(0, 16); // 16 = 16 ms debounce time

    void setup() {
    pinMode(led, OUTPUT);
    // Configure the pushbutton pins
    pinMode(0, INPUT_PULLUP);

    // audio library init
    AudioMemory(15);
    audioShield.enable();
    audioShield.volume(0.5);
    AudioNoInterrupts();
    sgtl5000_1.enable();
    sgtl5000_1.volume(0.5);
    AudioInterrupts();
    }

    void loop() {
    digitalWrite(led, LOW);
    float freqMult = (map(analogRead(A2),0,1023,1000,8000))/1000.0; // 0 - 4.0
    float level = 0.75;
    drum1.secondMix(level);
    float depth = 0.33;
    drum1.pitchMod(depth);
    float length_ms = 500.0; // length = 500 ms
    drum1.length(length_ms);

    buttonDrum1.update();
    if (buttonDrum1.fallingEdge()) {
    drum1.noteOn();
    drum1.frequency(fkey*freqMult);
    delay(700);
    digitalWrite(led, HIGH);
    drum1.noteOn();
    drum1.frequency(fkey*freqMult*1.41);
    next = millis() + 600;
    while (next > millis()){}
    digitalWrite(led, LOW);
    drum1.noteOn();
    drum1.frequency(fkey*freqMult*0.707);
    }
    digitalWrite(led, HIGH);

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,750
    Quote Originally Posted by jcfrgmn View Post
    I do think there may be some interaction between the delay() and reverb or flanging, but we shall see.
    Please let me know if you come up with any test programs that clearly expose problems.

    Both of these were contributed code, and both seem to have quite a few issues. The reverb has a known problem where its output doesn't continue if it stops getting input data. It might also have noise or signal level problems, but so far no clear tests to reproduce those issues.

    Lately I haven't been able to put much dev time into the audio library, but I am collecting a long list of stuff to fix and improve when I get back to really putting time into audio.

  4. #4
    Junior Member jcfrgmn's Avatar
    Join Date
    Jun 2016
    Location
    Menlo Park, CA
    Posts
    10
    Paul, you rock! Thanks, I will probe a bit and let you know. Yes, I think the code might be as robust as yours.

  5. #5
    Junior Member
    Join Date
    Oct 2017
    Posts
    1
    Yes, Paul, thank you for this response!

  6. #6
    Senior Member MickMad's Avatar
    Join Date
    Feb 2013
    Location
    Italy
    Posts
    163
    Quote Originally Posted by jcfrgmn View Post
    I solved my own problem. The solution appears to be to either use delay() or a while loop with millis() as can be seen from the code below. I do think there may be some interaction between the delay() and reverb or flanging, but we shall see. The millis() test should be a good backup. Here is the working code for a 3 note drum melody.
    I had similar glitches using the flanger object and updating its values without a delay. The glitches become noticeable when the delay is below 100ms circa. In your previous code I see that you updated the flanger values at every loop; you might want to add a function that stores the values of the potentiometers that control the flanger values and have it update them only if there's been a change on the pots; this might still lead to glitches (as per what I just said before) but you won't constantly hear them.

Posting Permissions

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