Working version

This commit is contained in:
Aria
2025-11-23 19:14:24 -06:00
parent ca6a976351
commit 33ab0dc2c4
3 changed files with 29 additions and 20 deletions
+1 -1
View File
@@ -2170,7 +2170,7 @@ export const { speed } = registerControl('speed');
*
*/
export const { stretch } = registerControl('stretch');
export const { pitch } = registerControl('pitch');
export const { pshift } = registerControl('pshift');
/**
* Used in conjunction with `speed`, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`.
+7 -2
View File
@@ -531,9 +531,14 @@ export const superdough = async (value, t, hapDuration, cps = 0.5, cycle = 0.5)
}
const chain = []; // audio nodes that will be connected to each other sequentially
chain.push(sourceNode);
stretch !== undefined && chain.push(getWorklet(ac, 'pitch-processor', { pitchFactor: stretch }));
stretch !== undefined &&
chain.push(
getWorklet(ac, 'pitch-processor', { pitchFactor: stretch }, { processorOptions: { vocoderMode: true } }),
);
pshift !== undefined &&
chain.push(getWorklet(ac, 'pitch-processor', { pitchFactor: pshift }, { processorOptions: { mode: 1 } }));
chain.push(
getWorklet(ac, 'pitch-processor', { pitchFactor: pshift }, { processorOptions: { vocoderMode: false } }),
);
// gain stage
chain.push(gainNode(gain));
+21 -17
View File
@@ -580,10 +580,13 @@ class PitchProcessor extends OLAProcessor {
}
constructor(options) {
options.processorOptions = {
blockSize: BUFFERED_BLOCK_SIZE,
const parentOptions = {
...options,
processorOptions: {
blockSize: BUFFERED_BLOCK_SIZE,
},
};
super(options);
super(parentOptions);
// if true, use spectral peak-finding to cluster strong bins ('stretch')
// else, use simple shift & interpolate ('pitch')
@@ -600,7 +603,6 @@ class PitchProcessor extends OLAProcessor {
this.freqComplexBufferShifted = this.fft.createComplexArray();
this.timeComplexBuffer = this.fft.createComplexArray();
this.timeCursor = 0;
this.vocoderMode = this.mode === 0;
// for peak tracking in phase vocoder mode
if (this.vocoderMode) {
@@ -651,6 +653,19 @@ class PitchProcessor extends OLAProcessor {
}
}
writeShiftedBin(destBin, valueReal, valueImag, phaseShiftReal, phaseShiftImag, accumulate) {
const shiftedReal = valueReal * phaseShiftReal - valueImag * phaseShiftImag;
const shiftedImag = valueReal * phaseShiftImag + valueImag * phaseShiftReal;
const destIndex = destBin * 2;
if (accumulate) {
this.freqComplexBufferShifted[destIndex] += shiftedReal;
this.freqComplexBufferShifted[destIndex + 1] += shiftedImag;
} else {
this.freqComplexBufferShifted[destIndex] = shiftedReal;
this.freqComplexBufferShifted[destIndex + 1] = shiftedImag;
}
}
/** Shift entire spectrum with simple resampling */
shiftSpectrum(pitchFactor) {
// zero-fill new spectrum
@@ -676,11 +691,7 @@ class PitchProcessor extends OLAProcessor {
const omegaDelta = TWO_PI * this.invfftSize * (destBin - sourceBin);
const phaseShiftReal = Math.cos(omegaDelta * this.timeCursor);
const phaseShiftImag = Math.sin(omegaDelta * this.timeCursor);
const shiftedReal = real * phaseShiftReal - imag * phaseShiftImag;
const shiftedImag = real * phaseShiftImag + imag * phaseShiftReal;
const destIndex = destBin * 2;
this.freqComplexBufferShifted[destIndex] = shiftedReal;
this.freqComplexBufferShifted[destIndex + 1] = shiftedImag;
this.writeShiftedBin(destBin, real, imag, phaseShiftReal, phaseShiftImag, false);
}
}
@@ -755,14 +766,7 @@ class PitchProcessor extends OLAProcessor {
const indexImag = indexReal + 1;
const valueReal = this.freqComplexBuffer[indexReal];
const valueImag = this.freqComplexBuffer[indexImag];
const valueShiftedReal = valueReal * phaseShiftReal - valueImag * phaseShiftImag;
const valueShiftedImag = valueReal * phaseShiftImag + valueImag * phaseShiftReal;
const indexShiftedReal = 2 * binIndexShifted;
const indexShiftedImag = indexShiftedReal + 1;
this.freqComplexBufferShifted[indexShiftedReal] += valueShiftedReal;
this.freqComplexBufferShifted[indexShiftedImag] += valueShiftedImag;
this.writeShiftedBin(binIndexShifted, valueReal, valueImag, phaseShiftReal, phaseShiftImag, true);
}
}
}