In article <n72dnUHBmot_yAPYnZ2dnUVZ_ternZ2d@giganews.com>,
"bobthebullet990" <bobthebullet990@hotmail.com> wrote:
| /* now add current audio sample to array and return oldest sample */
| delayArray[writePtr] = currentSample;
| /* does the sample at the required delay point exist? - interpolation
| */
| if ((delay + range) % flangerDelay)
| /* data sample exists, so return it! */
| return delayArray[readPtr];
| else
| /* the sample does not exist! interpolate nearest neighbours! */
| return(calculateAverage(delayArray[readPtr],delayArray[readPtr+1]));
You are using a circular buffer for the data. What happens when readPtr
is at the end, but you are accessing readPtr+1 in the above calculation?
-- Tim Olson
Reply by Tim Wescott●January 6, 20072007-01-06
bobthebullet990 wrote:
> Hi all! ...I am curious as to whether I am doing the right thing here or
> not! ...Im designing a flanger effect, but what is known as the "zipper
> effect" is occuring when i run my algorithm (using the C6711 DSK). I am
> confused as to exactly why, because after reading many articles on
> interpolation, it seems to me like im doing the correct thing! please may
> anyone have a look and let me know... my flanger function is here... [with
> a psuedo code main function to show it is being used]...
>
-- eww, code: snip --
>
>
You'll find that folks often don't go through code on this, or any other
group. Mostly because it's _work_. Perhaps you'll get lucky, but if
not it may help to post an outline of your algorithm as a bulleted list
of no more than five lines. If you use more, get more general.
In the mean time I would suggest that you make a really stupid,
bone-headed implementation that uses tons of processor ticks and memory
but is guaranteed correct, then go back from there to where you want to be.
Something like:
* Take your original audio clip.
* Resample and interpolate it to 1MS/s.
* Downsample it, with flanging.
* Play it.
The only two things you can screw up here are the resampling and the
flanging -- and if replace the flanging with a straight downsampling
then you can't screw _that_ up either. Once you get that working, then
work on doing it using more compact methods, and making it work in real
time.
--
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Posting from Google? See http://cfaj.freeshell.org/google/
"Applied Control Theory for Embedded Systems" came out in April.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply by bobthebullet990●January 5, 20072007-01-05
Hi all! ...I am curious as to whether I am doing the right thing here or
not! ...Im designing a flanger effect, but what is known as the "zipper
effect" is occuring when i run my algorithm (using the C6711 DSK). I am
confused as to exactly why, because after reading many articles on
interpolation, it seems to me like im doing the correct thing! please may
anyone have a look and let me know... my flanger function is here... [with
a psuedo code main function to show it is being used]...
int main(void){
/* loop until user switches off flanger effect */
/* 1.read input and convert to mono */
/* 2.read switches on DSK and change range and rate if need be */
/* NOTE: Delay is const, set to 10samples ~aprox~0.5ms sample rate */
/* is set to 22.4 kHz. */
/* 3.send current sample to flanger function and output return data
*/
/* end of loop */
return 0;
}
/*************************************************************************/
/**
**/
/** FUNCTION : flanger
**/
/** DESCRIPTION : Function to apply a flanger effect to the input data.
**/
/** This function returns the flanged audio data sample
**/
/** by sample as it is called. It requires parameters:
**/
/** + range - determines the range of delay values for
**/
/** the sweep triangular waveform /\/\/\/
**/
/** + delay - the constant delay term to apply
**/
/** + rate - the rate at which the sweep triangular wave-
**/
/** form should change [every x samples]
**/
/** + currentSample - latest audio sample from codec
**/
/**
**/
/*************************************************************************/
short int flanger(int range, int delay, int rate, short int
currentSample){
int flangerDelay; /* stores current delay required for flange effect */
static int i=0; /* keeps track of time for creating sweep waveform */
static int sweepValue=0; /* to keep track of current sweep delay */
static int sweepFlag=1; /* keeps track of waveform movement */
static int writePtr=0; /* pointer to newest audio sample in buffer */
static int readPtr=0; /* pointer to oldest audio sample in buffer */
/* is it time to change waveform movement? if not, increment counter */
if (i >= rate) {
/* has the maximum possible delay for sweep been reached? */
if (sweepValue >= range)
sweepFlag = 0; /* start the \ of triangular waveform */
else if (sweepValue <= 0)
sweepFlag = 1; /* start the / of triangular waveform */
/* Is the waveform rising or falling? */
if (sweepFlag==1)
sweepValue++;
else
sweepValue--;
/* reset i, to start count before waveform changes shape again */
i=0;
}
else i++;
/* Calculate the total current to delay */
flangerDelay = sweepValue + delay;
/* Calculate position of the read & write pointers */
if (flangeHead < flangerDelay)
readPtr = MAX_DELAY - (flangerDelay - writePtr);
else
readPtr = writePtr - flangerDelay;
/* has the write pointer reached end of delay buffer? */
if (writePtr > MAX_DELAY)
writePtr=0;
else
writePtr++;
/* now add current audio sample to array and return oldest sample */
delayArray[writePtr] = currentSample;
/* does the sample at the required delay point exist? - interpolation
*/
if ((delay + range) % flangerDelay)
/* data sample exists, so return it! */
return delayArray[readPtr];
else
/* the sample does not exist! interpolate nearest neighbours! */
return(calculateAverage(delayArray[readPtr],delayArray[readPtr+1]));
} /* flanger() */
Many thanks! Matt.