@audio/shift-pvoc-lock 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +39 -0
  2. package/package.json +40 -0
package/index.js ADDED
@@ -0,0 +1,39 @@
1
+ import { makeStftShift } from '@audio/shift-core/stft'
2
+ import { findPeaks, scatterLocked, makeFrameRatio } from '@audio/shift-core'
3
+
4
+ // Peak-locked phase vocoder (Laroche-Dolson style, adapted to direct bin-shift pitch shifting).
5
+ // Phase coherence across a region of influence is preserved by locking non-peak bins' phase
6
+ // relative to the nearest magnitude peak, rather than advancing every bin independently.
7
+ // Batch and stream share this exact per-frame kernel (see shift-core's scatterLocked energy
8
+ // policy) so no post-hoc gain correction is needed.
9
+
10
+ function process(mag, phase, state, ctx) {
11
+ if (!state.fr) state.fr = makeFrameRatio(ctx.ratioFn || ctx.ratio || 1)
12
+ let { half } = ctx
13
+ let ratio = state.fr.at(ctx.frameStart, ctx.sampleRate)
14
+ if (!state.prev) {
15
+ state.prev = new Float64Array(half + 1)
16
+ state.syn = new Float64Array(half + 1)
17
+ state.newMag = new Float64Array(half + 1)
18
+ state.newPhase = new Float64Array(half + 1)
19
+ state.peakMag = new Float64Array(half + 1)
20
+ state.peakDest = new Int32Array(half)
21
+ state.peakSynPhase = new Float64Array(half)
22
+ state.first = true
23
+ }
24
+
25
+ let { prev, syn, newMag, newPhase, peakMag, peakDest, peakSynPhase } = state
26
+ newMag.fill(0)
27
+ newPhase.fill(0)
28
+ peakMag.fill(0)
29
+
30
+ let peaks = findPeaks(mag, half)
31
+ scatterLocked(mag, phase, prev, state.first, peaks, ratio, ctx, syn, newMag, newPhase, peakDest, peakSynPhase, peakMag)
32
+
33
+ for (let k = 0; k <= half; k++) prev[k] = phase[k]
34
+ state.first = false
35
+
36
+ return { mag: newMag, phase: newPhase }
37
+ }
38
+
39
+ export default makeStftShift(process, { post: (out) => out })
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@audio/shift-pvoc-lock",
3
+ "version": "1.0.0",
4
+ "description": "Peak-locked phase vocoder (Laroche-Dolson) pitch shift",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "index.js",
8
+ "exports": {
9
+ ".": "./index.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "index.js"
14
+ ],
15
+ "dependencies": {
16
+ "@audio/shift-core": "^1.0.0"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "license": "MIT",
22
+ "author": "audiojs",
23
+ "homepage": "https://github.com/audiojs/shift/tree/main/packages/shift-pvoc-lock#readme",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/audiojs/shift.git",
27
+ "directory": "packages/shift-pvoc-lock"
28
+ },
29
+ "keywords": [
30
+ "audio",
31
+ "pitch-shift",
32
+ "phase-vocoder",
33
+ "peak-locked",
34
+ "laroche-dolson",
35
+ "dsp"
36
+ ],
37
+ "engines": {
38
+ "node": ">=18"
39
+ }
40
+ }