Ехото е доста просто. Имате нужда от линия за забавяне и малко умножение. Ако приемем, че един канал и аудиото вече са представени с плаваща запетая, линията на забавяне ще изглежда така (в C-подобен псевдокод):
int LENGTH = samplerate * seconds; //seconds is the desired length of the delay in seconds
float buffer[ LENGTH ];
int readIndex = 0, writeIndex = LENGTH - 1;
float delayLine.readNext( float x ) {
float ret = buffer[readIndex];
++readIndex;
if( readIndex >= LENGTH )
readIndex = 0;
return ret;
}
void delayLine.writeNext( float x ) {
buffer[ writeIndex ] = x;
++writeIndex;
if( writeIndex >= LENGTH )
writeIndex = 0;
}
Не забравяйте да инициализирате буфера до всички нули.
Така че това е вашата линия на забавяне. Основната употреба би била следната:
float singleDelay( float x ) {
delayLine.writeNext(x);
return delayLine.readNext( x );
}
Но няма да чуете голяма разлика: просто ще излезе по-късно. Ако искате да чуете едно ехо, ще ви трябва нещо подобно:
float singleEcho( float x, float g ) {
delayLine.writeNext(x);
return x + g * delayLine.readNext( x );
}
където g е някаква константа, обикновено между нула и едно.
Сега кажете, че искате поток от ехо: HELLO... Hello... hello... h... така. Просто трябва да свършите още малко работа:
float echo( float x, float g ) {
float ret = x + g * delayLine.readNext( x );
delayLine.writeNext( ret );
return ret;
}
Забележете как този път изходът от цялото нещо се връща обратно в линията на забавяне, а не входът. В този случай е много важно |g| ‹ 1.
Тук може да се натъкнете на проблеми с денормалните стойности. Не мога да си спомня дали това е проблем на iOS, но не мисля така.
person
Bjorn Roche
schedule
03.08.2012