Feeding delayed output back into input.

Feeding delayed output back into input.

Postby ArcAttack » Fri Nov 16, 2012 5:20 pm

Howdy.

First off the board is pretty sweet. Currently using it with an arduino uno and looking to get the maple.

After futzing around with the variable delay sketch, i was curious how i could go about feeding the delayed out put back into the input. Any suggestions on resources to help me figure this out? I

Thanks in advance!
ArcAttack
 
Posts: 9
Joined: Fri Nov 16, 2012 4:55 pm

Re: Feeding delayed output back into input.

Postby guest » Fri Nov 16, 2012 11:45 pm

feedback is a great idea. there are 2 ways to do this. one is digitally. you just take your output variable and add it back in with your input variable before you do any math. the downside to this is that it takes up more processor resources. you can also do it in analog with a potentiometer. just connect the top of the pot to HP_L, or HP_R which are the headphone outputs. connect the bottom of the pot to HP_C, which is ground. then connect the wiper to IN_L or IN_R. the pot will then allow you to control the level of feedback. a 10k pot should be fine, a log taper would be best, but probably doesnt matter too much.
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Re: Feeding delayed output back into input.

Postby ArcAttack » Sat Nov 17, 2012 1:39 am

guest wrote:feedback is a great idea. there are 2 ways to do this. one is digitally. you just take your output variable and add it back in with your input variable before you do any math. the downside to this is that it takes up more processor resources. you can also do it in analog with a potentiometer. just connect the top of the pot to HP_L, or HP_R which are the headphone outputs. connect the bottom of the pot to HP_C, which is ground. then connect the wiper to IN_L or IN_R. the pot will then allow you to control the level of feedback. a 10k pot should be fine, a log taper would be best, but probably doesnt matter too much.


Thanks guest! I had just figured the digital bit out right before I read that.

Now I'm having that darnedest time trying to get the serial monitor to work. I tried adding a

Serial.println(mod0_value);

and i cant seem to get it to function.

Code: Select all
#define SAMPLE_RATE 22 // 44.1kHz sample rate
#define ADCS 1 // only 1 ADC used here -> MOD0
#define LINVOL 20
// include necessary libraries
#include <Wire.h>
#include <SPI.h>
#include <AudioCodec.h>

// create data variables for audio transfer
// even though the function is mono, the codec requires stereo data
int left_in = 0; // in from codec (LINE_IN)
int right_in = 0;
int left_out = 0; // out to codec (HP_OUT)
int right_out = 0;

// create variable for ADC result
// it only has positive values -> unsigned
unsigned int mod0_value =0;

// create a delay buffer in memory
#define SIZE 800 // buffer size is limited by microcontroller SRAM size
int delaymem[SIZE]; // 800 positions x 2 bytes = 1600 bytes of SRAM
unsigned int location = 0; // buffer location to read/write from
unsigned int boundary = 0; // end of buffer position

void setup() {
  // call this last if you are setting up other things
 
  Serial.begin(9600);
  AudioCodec_init(); // setup codec and microcontroller registers
}

void loop() {
  while (1){
  int sensorValue = mod0_value;
  //Serial.println(sensorValue); //if this isnt commented out then the program freezes
 
  };
  // reduces clock jitter
}

// timer1 interrupt routine - all data processed here
ISR(TIMER1_COMPA_vect, ISR_NAKED) { // dont store any registers

  // &'s are necessary on data_in variables
  AudioCodec_data(&left_in, &right_in, left_out, right_out);
 
  // pass left input to right output
  right_out = left_out;

  //fetch data from buffer and put it into output register
  left_out = delaymem[location];
  // put new data in same location for maximal delay time
  delaymem[location++] = left_in + (left_out * .95); // post increment location to go to next memory location
  // check if location has gotten bigger than buffer size
  //left_in = left_out;
  if (location >= boundary) {
    location = 0; // reset location
  }

  // & is required before adc variable
  AudioCodec_ADC(&mod0_value);

  // scale ADC value to match buffer size
  // note the use of the fancy fast math function
  // you can read about these in the readme file
  unsigned int scale = SIZE;
  unsigned int newmod;
  if (mod0_value > 30000)
      {
      newmod = 11000;
      }
  if (mod0_value < 30000)
    {
     if (mod0_value > 10000)
         {
      newmod = 16500;//low?
         }
         else
         {
      newmod = 22000;}
     
    }
 // if (mod0_value < 1)
   //  {newmod = 44000;}
  MultiU16X16toH16(boundary, newmod, scale);

  reti(); // dont forget to return from the interrupt
}
ArcAttack
 
Posts: 9
Joined: Fri Nov 16, 2012 4:55 pm

Re: Feeding delayed output back into input.

Postby guest » Sat Nov 17, 2012 10:40 am

im not sure if serial can work with the codecshield. there arent too many free clock cycles, and i think it is blocking, which means it doesnt let other things happen while it is processing. you can try running it at its fastest rate, and see if that helps.

one other thing that you will have to do, to get any code to run in the loop() section, is to change the interrupt declaration. right now it is like this:

Code: Select all
ISR(TIMER1_COMPA_vect, ISR_NAKED) { // dont store any registers
// some code here
reit();
}


you should change it to:

Code: Select all
ISR(TIMER1_COMPA_vect) { // store registers
// some code here
// no reti
}


this will allow the main loop() to have its variables saved when the interrupt is called, otherwise the interrupt just clobbers them all.

if none of that works, i can give you some code that will work, its just that the arduino libraries are too bulky to work with the fast processing required by the codecshield.
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Re: Feeding delayed output back into input.

Postby guest » Sat Nov 17, 2012 10:43 am

i knew i had looked at this before. here is a forum post describing exactly what you want to do:

viewtopic.php?f=21&t=302
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Re: Feeding delayed output back into input.

Postby ArcAttack » Sat Nov 17, 2012 12:54 pm

Ok here is the loop code:

Code: Select all
void loop() {
  while (1){
 if (Serial.available() > 0) {
      // read the oldest byte in the serial buffer:
      // mod1_value = Serial.read() << 8;
       Serial.println(mod1_value)
     }
  };
  // reduces clock jitter
}



and i took out isnaked and reti; but still no luck :-/
ArcAttack
 
Posts: 9
Joined: Fri Nov 16, 2012 4:55 pm

Re: Feeding delayed output back into input.

Postby guest » Sat Nov 17, 2012 1:32 pm

are you running this on an UNO or Dueminlaove? also, when did you download the library, and which one did you grab? i will double check that this all works.
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Re: Feeding delayed output back into input.

Postby guest » Sat Nov 17, 2012 2:15 pm

ok, so here is probably what the problem is: mod0_value gets modified only in the interrupt, so the main code has no idea that it is changing, and therefore compiles out the (aparantly) non-used code. to fix this, mod0_value needs to become volatile, which tells the compiler that it might be changing elsewhere. but, its not defined that way in the library, so it cant be declared volatile directly. to work around this, do the following:

Code: Select all
volatile unsigned int serial_out = 0;

void loop() {
  if (Serial.available() > 0) {
    Serial.println(serial_out)
   }
}

and then in the interrupt:

serial_out = mod0_value;
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Re: Feeding delayed output back into input.

Postby ArcAttack » Sat Nov 17, 2012 3:11 pm

So I tried that. The program runs fine but still no Serial communication through the serial monitor.

Thanks again for the help!



guest wrote:ok, so here is probably what the problem is: mod0_value gets modified only in the interrupt, so the main code has no idea that it is changing, and therefore compiles out the (aparantly) non-used code. to fix this, mod0_value needs to become volatile, which tells the compiler that it might be changing elsewhere. but, its not defined that way in the library, so it cant be declared volatile directly. to work around this, do the following:

Code: Select all
volatile unsigned int serial_out = 0;

void loop() {
  if (Serial.available() > 0) {
    Serial.println(serial_out)
   }
}

and then in the interrupt:

serial_out = mod0_value;
ArcAttack
 
Posts: 9
Joined: Fri Nov 16, 2012 4:55 pm

Re: Feeding delayed output back into input.

Postby guest » Sat Nov 17, 2012 4:00 pm

i ran it on my arduino, and it worked, but i had to send a character first before the serial was recognized. try sending a character in the serial monitor, that should activate the serial.available(). are you calling serial.begin() before the codec initialization?
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Next

Return to Audio Codec Shield

Who is online

Users browsing this forum: Majestic-12 [Bot] and 1 guest


cron