Granular Effect Detailed documation not appeared for Teensy using PSRAM!

charnjit

Well-known member
Am sorry to make this post related to my previuos one. but i need to solve it first to go ahead for teensyAudio.
i have teensy4.1 with 2 chip PSRAM+Audio Adaptor.
i wanted Playback speed control of my 2 sec drum loop(real-time or set once before call to play drum loop ) without affect its pitch. i have a lot of use of "TeensyVariablePlayback" but in this i was getting pitch affected with speed of drum loop "01.wav" i was playing my drum loop in repeat mode seamlessly. finaly i found Granular is best for my requirment . i start search on use of this object but i could not found more.
what i found , i tried myself. not got a successfull result. As below code you see , first i have to re-load my drum loop into PSRAM ,while i have loaded in Void setup ()
. before any changes to speed drum loop is being hear Not on original quality(something missing in start of loop every time)
and when i made Speed(1.4) inceament.. got playing file stopped. when drum loop stopped once , it is not able to replay.
plaese took a look on code:
C++:
#include <Arduino.h>
#include <Audio.h>
#include <SD.h>
#include <TeensyVariablePlayback.h>       
#include <SPI.h>
#include <Wire.h>                                   //  USB TYPE : SERIAL + MIDI + AUDIO

AudioPlaySdResmp        playSdWav1;
AudioPlaySdResmp        playSdWav2;

AudioEffectGranular   granular1;

AudioPlayArrayResmp  playArrayWav1;
AudioPlayArrayResmp  playArrayWav2;
AudioPlayArrayResmp  playArrayWav3;
AudioPlayArrayResmp  playArrayWav4;

AudioPlayArrayResmp *playArray[] = {
                                       &playArrayWav1,
                                       &playArrayWav2,
                                       &playArrayWav3,
                                       &playArrayWav4};

  AudioMixer4            mixer1;
  AudioMixer4              mixer2;

  AudioOutputI2S i2s2;

  AudioConnection          patchCord1(playSdWav1, 0, mixer2, 0);
AudioConnection          patchCord2(playSdWav1, 0, mixer2, 1);
AudioConnection          patchCord3(playArrayWav1, 0,granular1,0 );
AudioConnection          patchCord9(granular1,0,mixer1,0);
AudioConnection          patchCord4(playArrayWav2, 0, mixer1, 1);
AudioConnection          patchCord5(playArrayWav3, 0, mixer1, 2);
AudioConnection          patchCord6(playArrayWav4, 0, mixer1, 3);
AudioConnection          patchCord7(mixer1, 0, i2s2, 1);
AudioConnection          patchCord8(mixer1, 0, i2s2, 0);

AudioControlSGTL5000 audioShield;

#define NUM_WAVS 16 // avoid silly mistakes

float Speed = 1.00;

const char *SMP_WAV[NUM_WAVS] = { "01.WAV", "02.WAV", "03.WAV", "04.WAV", "05.WAV", "06.WAV", "07.WAV", "08.WAV", "09.WAV", "10.WAV", "11.WAV", "12.WAV", "13.WAV", "14.WAV", "15.WAV", "16.WAV" };
File x_File;
int16_t *SMP_addr[NUM_WAVS];
uint32_t sizes[NUM_WAVS];

void setup()       {
                       Serial.begin(57600);
                         if (!(SD.begin(BUILTIN_SDCARD))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
          AudioMemory(128);
         audioShield.enable();                                               
         audioShield.volume(0.5);
             for (int i = 0; i < 4; i++)  {
                                           playArray[i]->enableInterpolation(true);
                                           }
                  RAM_LOAD ();  // load my wav samples to PSRAM
          granular1.begin(SMP_addr[0],sizes[0]);             
                    }

                    void loop() {

                      //----------------------SERIAL.AVALABLE-------------------------
  if (Serial.available() > 0) {
    String incomingByte = Serial.readString();                           
                           incomingByte.trim();   
                         if (incomingByte=="1") {
                                          
                                           playArray[0]->playWav(SMP_addr[0]);  // Start PLAYER
                                           playArray[0]->setLoopType(looptype_repeat);
                                             granular1.begin(SMP_addr[0],sizes[0]);
                                               granular1.beginFreeze(sizes[0]);
                                                }
      
                          if (incomingByte=="0") {
                                           granular1.stop();   // Stop PLAYRER
                                           playArray[0]->stop();   
                                           playArray[1]->stop();
                                            granular1.stop();
                                                }
                              if (incomingByte=="S") {
                                           granular1.stop();
                                                    }
                               if (incomingByte=="M") {
                                                     Speed= 1.4;   
                                                     granular1.setSpeed(Speed);
                                                     granular1.beginFreeze(sizes[0]);
                                                    Serial.println(Speed);
                                                    }
                                     if (incomingByte=="FREE") {
                                                   FREE_RAM ();
                                     }
                                      if (incomingByte=="LOAD") {    // Re-load my wav Samples to PSRAM
                                                       granular1.stop();
                                                       RAM_LOAD ();
                                                       granular1.begin(SMP_addr[0],sizes[0]);  // sizes[0]
                                     }
                            }
                           //----------------------SERIAL.AVALABLE-------------------------
                              granular1.setSpeed(Speed);
                    }
                void RAM_LOAD ()  {                 
              
  int SMP_FILE_NUM=0;
  for (int i = 0; i < NUM_WAVS; i++) {
                              x_File = SD.open(SMP_WAV[i], FILE_READ);
                             if (x_File)
                                         {
      sizes[i] = x_File.size();
      SMP_addr[i] = (int16_t*) extmem_malloc(sizes[i]);
      if (nullptr == SMP_addr[i])
        Serial.printf("Failed to allocate %d in EXTMEM for %s\n", sizes[i], SMP_WAV[i]);
      else     {
        if (sizes[i] != x_File.read(SMP_addr[i], sizes[i]))     
        {
          Serial.printf("Failed to read in %s - wrong length\n", SMP_WAV[i]);
          extmem_free(SMP_addr[i]); // free memory
          SMP_addr[i] = nullptr;    // mark as "not loaded"
        }
        else
          Serial.printf("Read %s into memory at %08X; %d bytes\n", SMP_WAV[i], SMP_addr[i], sizes[i]);
      }
      x_File.close();
    }
    else
      Serial.printf("Failed to open %s\n", SMP_WAV[i]);
  }
}
                 void FREE_RAM () {     //  FREE_RAM ();
                   for (int i = 0; i < NUM_WAVS; i++)
                                                            {   
                                                              if (nullptr != SMP_addr[i]) { extmem_free(SMP_addr[i]);   Serial.println("Clear: "); Serial.println(i); }
                                                              else {Serial.println("Already Free");}
                                                              }  Serial.println("Cleared");
                 }

i have tried many values for granular.beginFreeze(); but no good changes.
by the way , i have many drum loops (2-6sec long) what i want to load into psram and play them in repeat mode seamlessly.also want to play random file when one is
being played.
01 WAV IMAGE.jpg

in Future i want to call play more drum loops to play from more buttons (According to availble PSRAM memory). please help me in fix one first.
i think there should be Detailed documation on this object to apply all types of audio in teensy. I would appreciate your help
thank you.....
 

Attachments

  • 01.zip
    292.7 KB · Views: 13
Wav files are being loaded to psram , and Played fine.but issue with "freeze()" parameter, or related to required function that help to" set speed()". I am not getting speed changes. But getting a small pitch up jerk in beginning of playing file in (loop mode)every Time. How to time stretch and manage grain size etc. without pitch affect?
 
Last edited:
could you help me . while not controlled playback speed with below code:
C++:
 float Speed = 1.0;
float currentSpeed = 1.0;
float baseFreezeDuration = 100.0;
void updatePlaybackSpeed(float newSpeed)  {
                                                 currentSpeed = newSpeed;
                                                float newDuration = baseFreezeDuration/currentSpeed;
                                                AudioNoInterrupts();
                                                granular1.beginFreeze(newDuration);
                                                AudioInterrupts();
                                                Serial.print("Speed : ");   Serial.println(currentSpeed);   
                                                Serial.print("New Frozen Duration");   Serial.println(newDuration);   
                                                  }
void setup()       {
                       granular1.begin(SMP_addr[0],sizes[0]); 
                       granular1.beginFreeze(100);
                   }
 void loop() {
                 if (incomingByte=="1") {    // call play audio
                                           playArray[0]->playWav(SMP_addr[0]); 
                                           playArray[0]->setLoopType(looptype_repeat);
                                                }
                  if (incomingByte=="M") {  // call speed slower
                                          Speed= 0.5;
                                        updatePlaybackSpeed(Speed);
                                                    }
                      if (incomingByte=="N") {   // call speed faster
                                       Speed = 1.5;
                                        updatePlaybackSpeed(Speed);
                                                    }
                    granular1.setSpeed(Speed);   // call forever in loop
              }
 
Not something in my wheelhouse.

But, wondering does this same idea work from RAM1, RAM2, or SD card, or FLASH memory storage?
 
Back
Top