Skip to content

Commit d5fa304

Browse files
committed
Nevermind this commit.
1 parent 5954687 commit d5fa304

File tree

5 files changed

+476
-138
lines changed

5 files changed

+476
-138
lines changed

PV.js

+37-1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,42 @@ function PhaseVocoder(winSize, sampleRate) {
166166
return {peaks: peaks, inflRegionStart: inflRegStart, inflRegionEnd: inflRegEnd};
167167
}
168168

169+
this.find_peaks_v4 = function(magFrame) {
170+
var magSpecPad = [0,0].concat(magFrame).concat([0,0]);
171+
var peaks = [];
172+
173+
for (var i=2, I=0; i<=magSpecPad.length-2; i++, I++) {
174+
x = magSpecPad[i];
175+
if (x > magSpecPad[i-2] && x > magSpecPad[i-1] && x > magSpecPad[i+1] && x > magSpecPad[i+2]) {
176+
peaks = peaks.concat(I);
177+
}
178+
}
179+
180+
var inflRegStart = new Array(peaks.length);
181+
182+
inflRegStart[0] = 0;
183+
for (var i=0; i<peaks.length-1; i++) {
184+
inflRegStart[i+1] = Math.ceil((peaks[i] + peaks[i+1])/2);
185+
}
186+
187+
var inflRegEnd = new Array(peaks.length);
188+
for (var i=1; i<inflRegStart.length; i++) {
189+
inflRegEnd[i-1] = inflRegStart[i]-1;
190+
}
191+
inflRegEnd[inflRegEnd.length] = inflRegEnd.length-1;
192+
193+
// var influenceRegions = new Array(inflRegionStart.length);
194+
// for (var i=0; i<influenceRegions.length; i++)
195+
// influenceRegions[i] = Math.max(0, inflRegionEnd[i] - inflRegionStart[i] + 1);
196+
197+
return {
198+
peaks: peaks,
199+
inflRegionStart: inflRegStart,
200+
inflRegionEnd: inflRegEnd,
201+
// influenceRegions: influenceRegions
202+
};
203+
}
204+
169205
/*
170206
* Returns the instantaneous phase advances per synthesis hopsize.
171207
*
@@ -252,7 +288,7 @@ function PhaseVocoder(winSize, sampleRate) {
252288
this.identity_phase_locking_v2 = function(currentInputMagnitude, currentInputPhase, previousOutputPhase, instPhaseAdv) {
253289
var _ = this;
254290

255-
var r = _.find_peaks_v3(currentInputMagnitude);
291+
var r = _.find_peaks_v4(currentInputMagnitude);
256292

257293
var influenceRegions = new Array(r.inflRegionStart.length);
258294

PV_fast.js

+79-63
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function PhaseVocoder(winSize, sampleRate) {
1212

1313

1414

15-
this.overlap_and_slide = function(RS, frame, overlapBuffer, windowSize, finishedBytes) {
15+
function overlap_and_slide(RS, frame, overlapBuffer, windowSize, finishedBytes) {
1616

1717
for (var i=0; i<RS; i++) {
1818
finishedBytes[i] = overlapBuffer.shift();
@@ -36,7 +36,7 @@ function PhaseVocoder(winSize, sampleRate) {
3636
}
3737

3838

39-
this.find_peaks = function(magFrame, out) {
39+
function find_peaks(magFrame, out) {
4040
var magSpecPad = [0,0].concat(magFrame).concat([0,0]);
4141
out.peaks = [];
4242

@@ -68,14 +68,14 @@ function PhaseVocoder(winSize, sampleRate) {
6868
}
6969

7070

71-
this.get_phase_advances = function(currentInputPhase, previousInputPhase, omega, RA, RS, instPhaseAdvHop) {
71+
function get_phase_advances(currInPh, prevInPh, omega, RA, RS, instPhaseAdvHop) {
7272
var twoPI = 2 * Math.PI;
7373

7474
for (var i=0; i<omega.length; i++) {
7575
var expectedPhaseAdv = omega[i] * RA;
7676

77-
var auxheterodynedPhaseIncr = (currentInputPhase[i] - previousInputPhase[i]) - expectedPhaseAdv;
78-
var heterodynedPhaseIncr = auxheterodynedPhaseIncr - twoPI * Math.round(auxheterodynedPhaseIncr/twoPI);
77+
var auxHeterodynedPhaseIncr = (currInPh[i] - prevInPh[i]) - expectedPhaseAdv;
78+
var heterodynedPhaseIncr = auxHeterodynedPhaseIncr - twoPI * Math.round(auxHeterodynedPhaseIncr/twoPI);
7979

8080
var instPhaseAdvPerSampleHop = omega[i] + heterodynedPhaseIncr / RA;
8181

@@ -86,73 +86,73 @@ function PhaseVocoder(winSize, sampleRate) {
8686
}
8787

8888

89-
this.get_phasor_theta_v2 = function(currentInputPhase, previousOutputPhase, instPhaseAdv, frequencyBins, influenceRegions, theta) {
89+
function get_phasor_theta(currInPh, prevOutPh, instPhaseAdv, frequencyBins, inflRegs, theta) {
9090
// Get the peaks in the spectrum together with their regions of influence.
9191

9292
var theta_idx = 0;
9393
for (var i=0; i<frequencyBins.length; i++) {
9494
var bin = frequencyBins[i];
95-
for (var j=0; j<influenceRegions[i]; j++, theta_idx++) {
96-
theta[theta_idx] = previousOutputPhase[bin] + instPhaseAdv[bin] - currentInputPhase[bin];
95+
for (var j=0; j<inflRegs[i]; j++, theta_idx++) {
96+
theta[theta_idx] = prevOutPh[bin] + instPhaseAdv[bin] - currInPh[bin];
9797
}
9898
}
9999

100-
var remaining_length = theta.length - theta_idx;
101-
for (var i=0; i<remaining_length; i++, theta_idx++)
100+
var remainingLength = theta.length - theta_idx;
101+
for (var i=0; i<remainingLength; i++, theta_idx++)
102102
theta[theta_idx] = 0;
103103

104104
return;
105105
}
106106

107107

108-
this.identity_phase_locking = function(currentInputMagnitude, currentInputPhase, previousOutputPhase, instPhaseAdv, phasor_theta) {
108+
function identity_phase_locking(currInMag, currInPh, prevOutPh, instPhaseAdv, phTh) {
109109
var _ = this; var r = {};
110110

111-
_.find_peaks(currentInputMagnitude, r);
111+
find_peaks(currInMag, r);
112112

113-
_.get_phasor_theta_v2(currentInputPhase, previousOutputPhase, instPhaseAdv, r.peaks, r.influenceRegions, phasor_theta);
113+
get_phasor_theta(currInPh, prevOutPh, instPhaseAdv, r.peaks, r.influenceRegions, phTh);
114114

115115
return;
116116
}
117117

118-
this.pv_step_v2 = function(fftObject, previousInputPhase, previousOutputPhase, omega, RA, RS, out) {
119118

120-
var _ = this;
119+
function pv_step(fftObj, prevInPh, prevOutPh, omega, RA, RS, out) {
121120

122-
var currentInputPhase = fftObject.phase;
121+
var currInPh = fftObj.phase;
123122

124-
var instPhaseAdv = new Array(omega.length);
125-
_.get_phase_advances(currentInputPhase, previousInputPhase, omega, RA, RS, instPhaseAdv);
123+
var instPhaseAdv = new Float32Array(omega.length);
124+
get_phase_advances(currInPh, prevInPh, omega, RA, RS, instPhaseAdv);
126125

127-
var currentInputMag = fftObject.magnitude;
126+
var currInMag = fftObj.magnitude;
128127

129-
var phasor_theta = new Array(currentInputPhase.length);
130-
_.identity_phase_locking(currentInputMag, currentInputPhase, previousOutputPhase, instPhaseAdv, phasor_theta);
128+
var PhTh = new Float32Array(currInPh.length);
129+
identity_phase_locking(currInMag, currInPh, prevOutPh, instPhaseAdv, PhTh);
131130

132-
out.real = new Array((phasor_theta.length-1)*2);
133-
out.imag = new Array((phasor_theta.length-1)*2);
134-
out.phase = new Array((phasor_theta.length-1)*2);
135-
out.magnitude = new Array((phasor_theta.length-1)*2);
136-
var doubleSize = (phasor_theta.length-1)*2;
131+
var dblSize = (PhTh.length-1)*2;
132+
// out.real = new Float32Array(dblSize);
133+
// out.imag = new Float32Array(dblSize);
134+
// out.phase = new Float32Array(dblSize);
135+
// out.magnitude = new Float32Array(dblSize);
137136
var sqrt = Math.sqrt; var cos = Math.cos;
138137
var sin = Math.sin; var atan2 = Math.atan2;
139138

140139

141-
for (var i=0; i<phasor_theta.length; i++) {
142-
var theta = phasor_theta[i];
140+
for (var i=0; i<PhTh.length; i++) {
141+
var theta = PhTh[i];
143142

144-
var phasor_theta_real = cos(theta);
145-
var phasor_theta_imag = sin(theta);
146-
out.real[i] = phasor_theta_real * fftObject.real[i] - phasor_theta_imag * fftObject.imag[i];
147-
out.imag[i] = phasor_theta_real * fftObject.imag[i] + phasor_theta_imag * fftObject.real[i];
143+
var PhThRe = cos(theta);
144+
var PhThIm = sin(theta);
145+
out.real[i] = PhThRe * fftObj.real[i] - PhThIm * fftObj.imag[i];
146+
out.imag[i] = PhThRe * fftObj.imag[i] + PhThIm * fftObj.real[i];
148147
out.phase[i] = atan2(out.imag[i], out.real[i]);
149148
out.magnitude[i] = sqrt(out.imag[i]*out.imag[i] + out.real[i]*out.real[i]);
150149

151150
if (i>0) {
152-
out.real[doubleSize-i] = out.real[i];
153-
out.imag[doubleSize-i] = -out.imag[i];
154-
out.phase[doubleSize-i] = atan2(out.imag[doubleSize-i], out.real[doubleSize-i]);
155-
out.magnitude[doubleSize-i] = sqrt(out.imag[doubleSize-i]*out.imag[doubleSize-i] + out.real[doubleSize-i]*out.real[doubleSize-i]);
151+
var idx = dblSize - 1;
152+
out.real[idx] = out.real[i];
153+
out.imag[idx] = -out.imag[i];
154+
out.phase[idx] = atan2(out.imag[idx], out.real[idx]);
155+
out.magnitude[idx] = sqrt(out.imag[idx]*out.imag[idx] + out.real[idx]*out.real[idx]);
156156
}
157157

158158
}
@@ -168,39 +168,56 @@ function PhaseVocoder(winSize, sampleRate) {
168168
var __RS = _RS;
169169
var __RA = _RA;
170170

171-
// -----------------------------
172-
// ----------FFT STEP-----------
173-
// -----------------------------
174-
175-
var fftObject = {};
176-
var out = {};
171+
// ----------------------------------
172+
// ----------ANALYSIS STEP-----------
173+
// ----------------------------------
174+
177175
var processedFrame = [];
178176

179177
if (_first) {
180-
_.STFT(inputFrame, _framingWindow, _winSize, fftObject);
181-
_previousOutputPhase = fftObject.phase;
182-
_previousInputPhase = fftObject.phase;
183-
processedFrame = new Array(fftObject.real.length);
184-
_.ISTFT(fftObject.real, fftObject.imag, _framingWindow, true, processedFrame);
178+
var fftObj = {
179+
real: new Float32Array(_winSize),
180+
imag: new Float32Array(_winSize),
181+
magnitude: new Float32Array(_winSize),
182+
phase: new Float32Array(_winSize)
183+
};
184+
_.STFT(inputFrame, _framingWindow, _winSize, fftObj);
185+
_previousOutputPhase = fftObj.phase;
186+
_previousInputPhase = fftObj.phase;
187+
processedFrame = new Float32Array(fftObj.real.length);
188+
_.ISTFT(fftObj.real, fftObj.imag, _framingWindow, false, processedFrame);
185189
} else {
186-
_.STFT(inputFrame, _framingWindow, Math.round(_winSize/2)+1, fftObject);
187-
_.pv_step_v2(fftObject, _previousInputPhase, _previousOutputPhase, _omega, __RA, __RS, out);
188-
_previousOutputPhase = out.phase;
189-
_previousInputPhase = fftObject.phase;
190-
processedFrame = new Array(out.real);
191-
_.ISTFT(out.real, out.imag, _framingWindow, true, processedFrame);
190+
var hlfSize = Math.round(_winSize/2)+1;
191+
var fftObj = {
192+
real: new Float32Array(hlfSize),
193+
imag: new Float32Array(hlfSize),
194+
magnitude: new Float32Array(hlfSize),
195+
phase: new Float32Array(hlfSize)
196+
};
197+
var pvOut = {
198+
real: new Float32Array(_winSize),
199+
imag: new Float32Array(_winSize),
200+
magnitude: new Float32Array(_winSize),
201+
phase: new Float32Array(_winSize)
202+
};
203+
_.STFT(inputFrame, _framingWindow, hlfSize, fftObj);
204+
pv_step(fftObj, _previousInputPhase, _previousOutputPhase, _omega, __RA, __RS, pvOut);
205+
_previousOutputPhase = pvOut.phase;
206+
_previousInputPhase = fftObj.phase;
207+
processedFrame = new Float32Array(pvOut.real);
208+
_.ISTFT(pvOut.real, pvOut.imag, _framingWindow, false, processedFrame);
192209
}
193210

194211
_first = false;
195212

196213

197-
// -----------------------------
198-
// ------OVERLAP AND SLIDE------
199-
// -----------------------------
214+
// ----------------------------------
215+
// ------OVERLAP AND SLIDE STEP------
216+
// ----------------------------------
200217
var outputFrame = [];
201-
_.overlap_and_slide(__RS, processedFrame, _overlapBuffers, _winSize, outputFrame);
218+
overlap_and_slide(__RS, processedFrame, _overlapBuffers, _winSize, outputFrame);
202219
var owFrame = [];
203-
_.overlap_and_slide(__RS, _squaredFramingWindow, _owOverlapBuffers, _winSize, owFrame);
220+
overlap_and_slide(__RS, _squaredFramingWindow, _owOverlapBuffers, _winSize, owFrame);
204221

205222
for (var i=0; i<outputFrame.length; i++)
206223
outputFrame[i] = outputFrame[i] / ((owFrame[i]<10e-3)? 1 : owFrame[i]);
@@ -210,7 +227,6 @@ function PhaseVocoder(winSize, sampleRate) {
210227
}
211228

212229

213-
214230
this.STFT = function(inputFrame, windowFrame, wantedSize, out) {
215231
var winSize = windowFrame.length;
216232
var _inputFrame = new Array(winSize);
@@ -222,10 +238,10 @@ function PhaseVocoder(winSize, sampleRate) {
222238
var fft = new FFT.complex(winSize, false);
223239
fft.simple(fftFrame, _inputFrame, 'real');
224240

225-
out.real = new Array(Math.min(winSize,wantedSize));
226-
out.imag = new Array(Math.min(winSize,wantedSize));
227-
out.magnitude = new Array(Math.min(winSize,wantedSize));
228-
out.phase = new Array(Math.min(winSize,wantedSize));
241+
// out.real = new Array(Math.min(winSize,wantedSize));
242+
// out.imag = new Array(Math.min(winSize,wantedSize));
243+
// out.magnitude = new Array(Math.min(winSize,wantedSize));
244+
// out.phase = new Array(Math.min(winSize,wantedSize));
229245

230246
for (var p=0; p<winSize && p<wantedSize; p++) {
231247
var real = out.real; var imag = out.imag;

0 commit comments

Comments
 (0)