Closed dcoredump closed 5 years ago
Ahhhh! I got it!!!
I have to use
m_osc.setRateAudio(1.0/AUDIO_BLOCK_SIZE);
Sorry, now I can go on with my chorus :-)
Regards, Holger
You're close, but not quite there.
Here's how the LFO works:
Normally you call getNextVector() inside the update() function of an AudioStream object, which is called exactly 44117/128 times per second.
In your example, your loop() must runs also at exactly 44117/128 times per second otherwise the LFO will be wrong. 344.6 Hz is roughly about 3ms per call.
You can fix your example by ensuring your loop() runs about once every 3 ms. Your example work fine for me when I used the following:
void loop() {
float v = *m_osc.getNextVector(); // gets 128 samples, but just grab the first one.
if (v * v_old < 0.0) // true if sign change occured
{
Serial.println("SIGN CHANGED!");
}
v_old = v;
delay(3); // delay for 3 ms, the code above runs very fast so the loop() takes about 3ms total.
}
I've been working on a Chorus as well but it won't be ready for a while. Also, keep in mind, when modulating delay with an LFO, you need delay values between the ones available in discrete delay line. in other works, you need to linearly interpolate fractional delay values between the audio samples in the delay line itself.
Many thanks! Since the class is called "*Vector", I could have gotten it :-)
I had the hope that I would "just" take an "AudioEffectDelay" and then calculate the time for a delay-tap using the LFO. So it's not so easy, too bad. Thanks for the hint!
What do you mean: Is a linear interpolation sufficient or do I have to use quadratic interpolation?
I'd say linear interpolation is the minimum. Using linear interp will likely introduce a very small amount of harmonic distortion. Using quadratic would reduce this distortion. Using spline even more so.
That said, the fun with guitar effects is they are anything but perfect. Analog choruses that uses bucket brigades introduce tons of artefacts and people like them because the imperfections make it sound more organic, as long as you filter out any high frequency artifacts.
I'd suggest using linear interpolation first, see how it sounds and if you're happy with that before taking it up a notch.
Puh, I tried to build a chorus out of the AudioAnlaogDelay and the LowFrequencyOscillatorVector for several hours and I'm too stupid to get it to work :-)
Here's the interesting part of the code - without interpolation for now:
// Chorus
size_t half_delay_samples=size_t(float(m_delaySamples)/2+0.5);
float *mod = lfo.getNextVector();
audio_block_t *lfoData = nullptr;
lfoData = allocate();
if (!lfoData) return;
for(uint8_t i=0;i<AUDIO_BLOCK_SAMPLES;i++)
{ m_memory->getSamples(lfoData,half_delay_samples+size_t((float(half_delay_samples)*mod[i]+0.5)),1);
blockToOutput->data[i]=lfoData[0];
}
The idea was to simply take the delay value with the index value modulated from the LFO for each sample. This sounds like a modulated sinus tone, but it sounds horrible!
Am I completely wrong? Perhaps I should wait until you have the solution, haha :-)
Regards, Holger
Here is my full AudioEffectSimpleChorus class: https://gist.github.com/dcoredump/48e0a286c782347f72cdb918461d5ac2
Having the delay jump between discrete delay values causes instantaneous changes in output that always create bad sound effects. Even commercial delay pedals do this when you adjust the delay knob fast enough. I don't think you an avoid the between-sample interpolation. Audio must always vary slowly enough that it doesn't exceed the Nyquist rate.
Step 1 for me was updating the AudioDelay component to support fractional delay values using linear interpolation. I've already done this on a development branch, but haven't pushed it up to github. It's only been tested as far as I can set a constant fractional delay in AudioEffectAnalogDelay and the audio sounds clean and the delay works. The next step was modulating that fractional delay with the LFO. I haven't got that far yet.
I might be able to take a look at it again this weekend and push the development branch up to github so you can look at the updated AudioDelay class object. That should let you experiment some more without waiting for me. Ping me again on this thread next week if you don't see a new branch pushed up.
I've pushed up some new code to the master of the repo (you don't need to worry about development branch). Take a look at the new function added to AudioDelay class called interpolatedDelay().
I've added a temporary file called "AudioEffectAnalogDelay.cpp.interpolated". This is a modified version that uses the new interpolated delay. The delay hardcodes an interpolation point 1/10th of the way between samples. I've tested it for audio fidelity to make sure the intepolated delay basically works. You can look at it as an example. Look for statements with:
#ifdef INTERPOLATED_DELAY
Hopefully this will help you in playing around with chorus since I double I'll be getting back to mine for at least a month, maybe two.
Hi. many thanks for this cool library and the nice hardware. Just ordered one :-)
I am trying to create a chorus effect on my own and tried to use your LowFrequencyOscillatorVector. But I am failing to get a simple 1 Hz sine wave. Am I doing something wrong?
This is my test code, which should IMHO produce two sign changes (one at AUDIO_SAMPLE_RATE_EXACT/2 and the next at AUDIO_SAMPLE_RATE_EXACT, for me AUDIO_SAMPLE_RATE_EXACT is 44117):
But I am getting something like 100 sign changes... what am I doing wrong?
Thanks, Holger