@@ -34,7 +34,7 @@ void MistralAudioProcessor::releaseResources()
3434{
3535 delayBuffer.clear ();
3636}
37-
37+ /*
3838void MistralAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
3939{
4040 juce::ScopedNoDenormals noDenormals;
@@ -100,6 +100,170 @@ void MistralAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce
100100 writePosition = 0;
101101 }
102102}
103+ */
104+
105+ /*
106+ void MistralAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
107+ {
108+ juce::ScopedNoDenormals noDenormals;
109+
110+ float targetRate = apvts.getRawParameterValue("rate")->load();
111+ float targetDepth = apvts.getRawParameterValue("depth")->load();
112+ float targetFeedback = apvts.getRawParameterValue("feedback")->load();
113+
114+ targetFeedback = juce::jmin(0.9f, targetFeedback);
115+
116+ // Инициализация сглаженных параметров при первом вызове
117+ static float smoothRate = targetRate;
118+ static float smoothDepth = targetDepth;
119+ static float smoothFeedback = targetFeedback;
120+
121+ // Коэффициент сглаживания (чем меньше, тем плавнее, но медленнее реакция)
122+ const float smoothing = 0.995f; // Быстрая, но плавная реакция (~1 мс)
123+
124+ // Плавное обновление параметров
125+ smoothRate = smoothRate * smoothing + targetRate * (1.0f - smoothing);
126+ smoothDepth = smoothDepth * smoothing + targetDepth * (1.0f - smoothing);
127+ smoothFeedback = smoothFeedback * smoothing + targetFeedback * (1.0f - smoothing);
128+
129+ float rate = smoothRate;
130+ float depth = smoothDepth;
131+ float feedback = smoothFeedback;
132+
133+ float lfoFreq = 0.1f + rate * 4.9f;
134+
135+ float minDelayMs = 0.5f;
136+ float maxDelayMs = 8.0f;
137+ float delayRangeMs = maxDelayMs - minDelayMs;
138+
139+ int numSamples = buffer.getNumSamples();
140+ int numChannels = buffer.getNumChannels();
141+
142+ for (int sample = 0; sample < numSamples; ++sample)
143+ {
144+ float lfo = std::sin(phase);
145+ lfo = (lfo + 1.0f) / 2.0f;
146+
147+ phase += 2.0f * juce::MathConstants<float>::pi * lfoFreq / sampleRate;
148+ if (phase >= juce::MathConstants<float>::twoPi)
149+ phase -= juce::MathConstants<float>::twoPi;
150+
151+ for (int channel = 0; channel < numChannels; ++channel)
152+ {
153+ float delayMs = minDelayMs + lfo * depth * delayRangeMs;
154+ float delaySamples = delayMs * sampleRate / 1000.0f;
155+
156+ float* channelData = buffer.getWritePointer(channel);
157+ float input = channelData[sample];
158+
159+ float readPos = (float)writePosition - delaySamples;
160+ if (readPos < 0) readPos += maxDelaySamples;
161+
162+ int readPosInt = (int)readPos;
163+ float frac = readPos - readPosInt;
164+ int readPosNext = readPosInt + 1;
165+ if (readPosNext >= maxDelaySamples) readPosNext = 0;
166+
167+ float delayed = delayBuffer.getSample(channel, readPosInt) * (1.0f - frac) +
168+ delayBuffer.getSample(channel, readPosNext) * frac;
169+
170+ float writeValue = input + delayed * feedback;
171+ writeValue = juce::jlimit(-1.0f, 1.0f, writeValue);
172+ delayBuffer.setSample(channel, writePosition, writeValue);
173+
174+ float output = input * (1.0f - depth) + delayed * depth;
175+
176+ channelData[sample] = output;
177+ }
178+
179+ writePosition++;
180+ if (writePosition >= maxDelaySamples)
181+ writePosition = 0;
182+ }
183+ }
184+ */
185+
186+ void MistralAudioProcessor::processBlock (juce::AudioBuffer<float >& buffer, juce::MidiBuffer& midiMessages)
187+ {
188+ juce::ScopedNoDenormals noDenormals;
189+
190+ float targetRate = apvts.getRawParameterValue (" rate" )->load ();
191+ float targetDepth = apvts.getRawParameterValue (" depth" )->load ();
192+ float targetFeedback = apvts.getRawParameterValue (" feedback" )->load ();
193+ targetFeedback = juce::jmin (0 .9f , targetFeedback);
194+
195+ static float smoothRate = targetRate;
196+ static float smoothDepth = targetDepth;
197+ static float smoothFeedback = targetFeedback;
198+
199+ // Плавное сглаживание (без адаптации для простоты)
200+ const float smoothing = 0 .995f ;
201+ smoothRate = smoothRate * smoothing + targetRate * (1 .0f - smoothing);
202+ smoothDepth = smoothDepth * smoothing + targetDepth * (1 .0f - smoothing);
203+ smoothFeedback = smoothFeedback * smoothing + targetFeedback * (1 .0f - smoothing);
204+
205+ float rate = smoothRate;
206+ float depth = smoothDepth;
207+ float feedback = smoothFeedback;
208+
209+ float lfoFreq = 0 .1f + rate * 4 .9f ;
210+
211+ float minDelayMs = 0 .5f ;
212+ float maxDelayMs = 8 .0f ;
213+ float delayRangeMs = maxDelayMs - minDelayMs;
214+
215+ int numSamples = buffer.getNumSamples ();
216+ int numChannels = buffer.getNumChannels ();
217+
218+ // === КЛЮЧЕВОЕ ИЗМЕНЕНИЕ: интерполяция позиции чтения ===
219+ static float currentDelaySamples = 0 .0f ;
220+
221+ for (int sample = 0 ; sample < numSamples; ++sample)
222+ {
223+ float lfo = std::sin (phase);
224+ lfo = (lfo + 1 .0f ) / 2 .0f ;
225+
226+ phase += 2 .0f * juce::MathConstants<float >::pi * lfoFreq / sampleRate;
227+ if (phase >= juce::MathConstants<float >::twoPi)
228+ phase -= juce::MathConstants<float >::twoPi;
229+
230+ // Целевая задержка на основе текущего depth
231+ float targetDelaySamples = (minDelayMs + lfo * depth * delayRangeMs) * sampleRate / 1000 .0f ;
232+
233+ // Плавная интерполяция позиции чтения (устраняет треск!)
234+ currentDelaySamples = currentDelaySamples * 0 .99f + targetDelaySamples * 0 .01f ;
235+
236+ for (int channel = 0 ; channel < numChannels; ++channel)
237+ {
238+ float * channelData = buffer.getWritePointer (channel);
239+ float input = channelData[sample];
240+
241+ float readPos = (float )writePosition - currentDelaySamples;
242+ if (readPos < 0 ) readPos += maxDelaySamples;
243+
244+ int readPosInt = (int )readPos;
245+ float frac = readPos - readPosInt;
246+ int readPosNext = readPosInt + 1 ;
247+ if (readPosNext >= maxDelaySamples) readPosNext = 0 ;
248+
249+ float delayed = delayBuffer.getSample (channel, readPosInt) * (1 .0f - frac) +
250+ delayBuffer.getSample (channel, readPosNext) * frac;
251+
252+ float writeValue = input + delayed * feedback;
253+ writeValue = juce::jlimit (-1 .0f , 1 .0f , writeValue);
254+ delayBuffer.setSample (channel, writePosition, writeValue);
255+
256+ float output = input * (1 .0f - depth) + delayed * depth;
257+
258+ channelData[sample] = output;
259+ }
260+
261+ writePosition++;
262+ if (writePosition >= maxDelaySamples)
263+ writePosition = 0 ;
264+ }
265+ }
266+
103267
104268void MistralAudioProcessor::processBlock (juce::AudioBuffer<double >& buffer, juce::MidiBuffer& midiMessages)
105269{
0 commit comments