OCTAVER

Hi
i wanna make a 1 or 2 Octave down audio pitch,from an line input to an output.
working on the pedalshield.
Instead of having only 3 position pot,i wanna get:
-pot fully clock wise normal sound
-and maybe 10 steps to get 1 or 2 octave down.
any idea? float divide?

[quote]// Licensed under a Creative Commons Attribution 3.0 Unported License.
// Based on rcarduino.blogspot.com previous work.
// www.electrosmash.com/pedalshield
 
/*octaver.ino creates an octave-up or octave-down signal from the original one.*/
 
int in_ADC0, in_ADC1;  //variables for 2 ADCs values (ADC0, ADC1)
int POT0, POT1, POT2, out_DAC0, out_DAC1; //variables for 3 pots (ADC8, ADC9, ADC10)
int LED = 3;
int FOOTSWITCH = 7; 
int TOGGLE = 2; 
int a = 3;
 float c = (float)a/2;
 
#define MAX_DELAY 4000
uint16_t sDelayBuffer0[MAX_DELAY-1];
uint16_t sDelayBuffer1[MAX_DELAY-1];
unsigned int write_pt=0;
unsigned int read_pt_A=0, read_pt_B= MAX_DELAY/2;
unsigned int Delay_Depth, increment, divider=0, buffer0, buffer1;
 
void setup()
{
  //turn on the timer clock in the power management controller
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(ID_TC4);
 
  //we want wavesel 01 with RC 
  TC_Configure(TC1, 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK2);
  TC_SetRC(TC1, 1, 238); // sets <> 44.1 Khz interrupt rate 109
  TC_Start(TC1, 1);
 
  // enable timer interrupts on the timer
  TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;
  TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;
 
  //Enable the interrupt in the nested vector interrupt controller 
  //TC4_IRQn where 4 is the timer number * timer channels (3) + the channel number 
  //(=(1*3)+1) for timer1 channel1 
  NVIC_EnableIRQ(TC4_IRQn);
 
  //ADC Configuration
  ADC->ADC_MR |= 0x80;   // DAC in free running mode.
  ADC->ADC_CR=2;         // Starts ADC conversion.
  ADC->ADC_CHER=0x1CC0;  // Enable ADC channels 0,1,8,9 and 10  
 
  //DAC Configuration
  analogWrite(DAC0,0);  // Enables DAC0
  analogWrite(DAC1,0);  // Enables DAC0
}
 
void loop()
{
  //Read the ADCs
  while((ADC->ADC_ISR & 0x1CC0)!=0x1CC0);// wait for ADC 0,1,8,9,10 conversion complete.
  in_ADC0=ADC->ADC_CDR[7];               // read data from ADC0
  in_ADC1=ADC->ADC_CDR[6];               // read data from ADC1  
  POT0=ADC->ADC_CDR[10];                 // read data from ADC8        
  POT1=ADC->ADC_CDR[11];                 // read data from ADC9   
  POT2=ADC->ADC_CDR[12];                 // read data from ADC10     
}
 
void TC4_Handler() //Interrupt at 44.1KHz rate (every 22.6us)
{
  TC_GetStatus(TC1, 1); //Clear status interrupt to be fired again.
 
  //Store current readings  
  sDelayBuffer0[write_pt] = in_ADC0;
  sDelayBuffer1[write_pt] = in_ADC1;
 
  //Adjust Delay Depth based in pot2 position.
  Delay_Depth = MAX_DELAY-1;
 
  //Increse/reset delay counter.
  write_pt++;
  if(write_pt >= Delay_Depth) write_pt = 0; 
 
  out_DAC0 = ((sDelayBuffer0[read_pt_A]));
  out_DAC1 = ((sDelayBuffer1[read_pt_B]));
 
  if (POT0>2700)
  { 
    read_pt_A = read_pt_A + 2;
    read_pt_B = read_pt_B + 2;
  }
 else if (POT0>1350)
  {
    read_pt_A = read_pt_A + 1;
    read_pt_B = read_pt_B + 1;
  }
 else
 {
   divider++;
   if (divider>=2)
   {
      read_pt_A = read_pt_A + 1;
      read_pt_B = read_pt_B + 1;
      divider=0;
    }
  }
 
  if(read_pt_A >= Delay_Depth) read_pt_A = 0; 
  if(read_pt_B >= Delay_Depth) read_pt_B = 0; 
 
  //Add volume control with POT2
  out_DAC0=map(out_DAC0,0,4095,1,POT2);
  out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
  //Write the DACs
  dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
  dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
  dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
  dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
}

Use code tags not quote tags.

What sort of Arduino are you running this on?

What you are asking is quite hard and the quality will not be great.

Hi
sorry for the tag
i'm on arduino Due
with the settings i've find the sound is pretty good.
the sound is pretty good for 1,2 or 3octave down, i would be as good for 1/2 octave or 1/3 octave down, right?
thansk for you reply!

No it is not as good as a none integer frequency shift.
Are you sure that that code gives you a frequency shift?

Can you modify that post to put it into code tags please.

I guess you are trying to change pitch by changing the sample rate... That works great and you can get good quality, but it also changes the speed (tempo). :o You probably don't want to change the speed, and slowing-down requires memory, since sound is going-in faster than it's coming-out. There are some "tricks" where you throw-away some delayed-slowed information to keep the tempo-up, but you don't get very good quality. (You don't always need "quality" with a guitar.)

And of course, you can't speed-up (to raise the pitch) in real-time (unless you allow gaps in the sound). Again, there are "tricks" of filling-in the gaps with repeated sound with associated quality issues.

Pitch shifting without changing speed is normally done with FFT. The Due might be able to handle that, but I'm not sure.

Well quality is important it's for vocal.
the quality is very good at 1 or 2 octave down,i'm impressed.
but add steps between normal and full 1 octave down is a trick...
ps:i didn't find the way to put code in code tag..

ps:i didn't find the way to put code in code tag..

Please read this:-
How to use this forum

DVDdoug:
Pitch shifting without changing speed is normally done with FFT. The Due might be able to handle that, but I'm not sure.

This is on my long-term wish list for the Teensy audio library. I have my eye on someday implementing this algorithm:

http://www.guitarpitchshifter.com/pitchshifting.html

It requires 4 overlapped FFT and 4 overlapped iFFT. On Teensy 3.2, we manage a 1024 point FFT in well under 2.9 ms, using the CMSIS-DSP 16 bit radix4 FFT. So there's perhaps some hope of getting 8 of them overlapped and crammed into every 23 ms (1024 samples at 44.1 kHz). I don't have a good feel for how much time the phase vocoder part will take. If it's even possible at all, I'm pretty sure it'll be a small feat to cram it all into the available CPU time at 96 MHz. When we have a 180 MHz Teensy, these computationally intensive algorithms should be much easier....

Due has the Cortex-M3 processor, which lacks the DSP extensions. Its FFTs will probably be about half the speed, so I doubt it could manage 44 kHz sample rate. But it might be possible with a 22.1 or 32 kHz sample rate?

Hi,
thanks for your reply,
no it doesn"t work, no change.

int in_ADC0, in_ADC1; //variables for 2 ADCs values (ADC0, ADC1)
int POT0, POT1, POT2, out_DAC0, out_DAC1; //variables for 3 pots (ADC8, ADC9, ADC10)
int LED = 3;
int FOOTSWITCH = 7;
int TOGGLE = 2;
static bool toggle = false;

strange