Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 4 additions & 57 deletions .github/workflows/main.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ name: CI
on:
pull_request:
branches: [master]
push:
branches: [master]
workflow_dispatch:
inputs:
reason:
description: 'Reason for manual trigger'
required: false
default: 'Manual release'

concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
validation:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest

permissions:
Expand All @@ -39,7 +35,6 @@ jobs:

- run: pnpm build

# Coverage summary chain (continue-on-error, always publish/upload/enforce)
- name: Generate coverage summary
id: coverage
run: pnpm coverage:summary
Expand Down Expand Up @@ -108,51 +103,3 @@ jobs:
- name: Enforce coverage summary status
if: steps.coverage.outcome == 'failure'
run: exit 1

release:
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && !startsWith(github.event.head_commit.message, 'chore(release)'))
runs-on: ubuntu-latest

permissions:
contents: write
id-token: write

steps:
- uses: actions/checkout@v6
with:
filter: tree:0
fetch-depth: 0

- uses: pnpm/action-setup@v6
name: Install pnpm
with:
version: 10.33.0
run_install: false

- name: Setup git creds
env:
config_email: ${{ secrets.GIT_CONFIG_EMAIL }}
config_un: ${{ secrets.GIT_CONFIG_USERNAME }}
run: |
git config --local user.email ${config_email}
git config --local user.name ${config_un}

- run: pnpm install --frozen-lockfile
env:
HUSKY: 0

- uses: nrwl/nx-set-shas@v5

- run: pnpm build

- name: Set up .npmrc for publishing
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish to npm
run: pnpm exec nx release --yes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
49 changes: 49 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CodeQL

on:
pull_request:
branches: [master]
types: [opened, reopened, synchronize, ready_for_review]
push:
branches: [master]
schedule:
- cron: '23 4 * * 1'

permissions:
actions: read
contents: read
security-events: write

concurrency:
group: codeql-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: codeql/analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [javascript-typescript]

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}

- uses: pnpm/action-setup@v6

- run: pnpm install --frozen-lockfile
env:
HUSKY: 0

- name: Build for analysis
run: pnpm build

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
67 changes: 67 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Release

on:
push:
branches: [master]
workflow_dispatch:
inputs:
dry_run:
description: Run nx release in dry-run mode
required: true
default: true
type: boolean

concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest

permissions:
contents: write
id-token: write

steps:
- uses: actions/checkout@v6
with:
filter: tree:0
fetch-depth: 0

- uses: pnpm/action-setup@v6
with:
version: 10.33.0
run_install: false

- name: Setup git creds
env:
config_email: ${{ secrets.GIT_CONFIG_EMAIL }}
config_un: ${{ secrets.GIT_CONFIG_USERNAME }}
run: |
git config --local user.email ${config_email}
git config --local user.name ${config_un}

- run: pnpm install --frozen-lockfile
env:
HUSKY: 0

- name: Set up .npmrc for publishing
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Run release dry-run
if: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }}
run: pnpm exec nx release --dry-run
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Run release
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && !inputs.dry_run) }}
run: pnpm exec nx release --yes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
27 changes: 21 additions & 6 deletions .github/workflows/storybook-pages.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
name: Deploy Storybook to GitHub Pages

on:
push:
branches: [master]
workflow_run:
workflows: [Release]
types: [completed]
workflow_dispatch:
inputs:
deploy:
description: Deploy to GitHub Pages after build
required: true
default: false
type: boolean

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: docs-pages-${{ github.ref }}
cancel-in-progress: false

jobs:
build:
if: github.event_name == 'workflow_dispatch' || startsWith(github.event.head_commit.message, 'chore(release)')
if: ${{ (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.ref }}

- uses: pnpm/action-setup@v6

Expand All @@ -30,16 +39,22 @@ jobs:
run: pnpm nx run @soundtouchjs/storybook:build-storybook

- name: Setup GitHub Pages
if: ${{ (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || inputs.deploy }}
uses: actions/configure-pages@v6

- name: Upload Storybook artifact
if: ${{ (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || inputs.deploy }}
uses: actions/upload-pages-artifact@v5
with:
path: ./static-storybook

deploy:
needs: build
if: ${{ (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || inputs.deploy }}
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A real-time audio processing library for pitch shifting and playback speed contr

## Monorepo

This project is an [Nx](https://nx.dev) monorepo managed with [pnpm](https://pnpm.io/) workspaces. It publishes ten packages:
This project is an [Nx](https://nx.dev) monorepo managed with [pnpm](https://pnpm.io/) workspaces. It publishes eleven packages:

| Package | npm | Description |
| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------ |
Expand All @@ -15,6 +15,7 @@ This project is an [Nx](https://nx.dev) monorepo managed with [pnpm](https://pnp
| [`@soundtouchjs/stretch-phase-vocoder`](packages/stretch-phase-vocoder/README.md) | `npm install @soundtouchjs/stretch-phase-vocoder` | Phase vocoder time-stretch algorithm — implements `StretchPipe`, usable standalone or as a `SoundTouch` stretch stage |
| [`@soundtouchjs/phase-vocoder-worklet`](packages/phase-vocoder-worklet/README.md) | `npm install @soundtouchjs/phase-vocoder-worklet` | AudioWorklet implementation using the phase vocoder for smoother extreme-ratio time-stretching |
| [`@soundtouchjs/formant-correction-worklet`](packages/formant-correction-worklet/README.md) | `npm install @soundtouchjs/formant-correction-worklet` | AudioWorklet implementation with LPC-based formant preservation for natural-sounding vocal pitch shifts |
| [`@soundtouchjs/worklet-base`](packages/worklet-base/README.md) | `npm install @soundtouchjs/worklet-base` | Abstract base class for building custom AudioWorklet processors on top of the SoundTouch engine |
| [`@soundtouchjs/interpolation-strategy-lanczos`](packages/interpolation-strategy-lanczos/README.md) | `npm install @soundtouchjs/interpolation-strategy-lanczos` | Lanczos interpolation strategy plugin (default strategy id: `lanczos`) |
| [`@soundtouchjs/interpolation-strategy-linear`](packages/interpolation-strategy-linear/README.md) | `npm install @soundtouchjs/interpolation-strategy-linear` | Linear interpolation strategy plugin (strategy id: `linear`) |
| [`@soundtouchjs/interpolation-strategy-hann`](packages/interpolation-strategy-hann/README.md) | `npm install @soundtouchjs/interpolation-strategy-hann` | Hann interpolation strategy plugin (strategy id: `hann`) |
Expand All @@ -37,6 +38,7 @@ If you are new to Web Audio, start with the demo guide: [apps/demo/README.md](ap
- Phase vocoder (time-stretch algorithm): [packages/stretch-phase-vocoder/README.md](packages/stretch-phase-vocoder/README.md)
- Phase vocoder AudioWorklet: [packages/phase-vocoder-worklet/README.md](packages/phase-vocoder-worklet/README.md)
- Formant correction AudioWorklet: [packages/formant-correction-worklet/README.md](packages/formant-correction-worklet/README.md)
- Custom worklet processor base class: [packages/worklet-base/README.md](packages/worklet-base/README.md)
- Beginner Web Audio + demo architecture guide: [https://cutterscrossing.com/SoundTouchJS/?path=/docs/getting-started--docs](https://cutterscrossing.com/SoundTouchJS/?path=/docs/getting-started--docs)

## Quick start
Expand Down
4 changes: 4 additions & 0 deletions packages/formant-correction-worklet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ import {
| Best use case | Instruments, music | Vocals, speech |
| `formantStrength = 0` mode | — | Identical to `SoundTouchNode` |

## Architecture

`FormantCorrectionProcessor` extends `SoundTouchProcessorBase` from `@soundtouchjs/worklet-base`, sharing the DSP pipeline, runtime-update queue, and `STANDARD_PARAMETER_DESCRIPTORS` with the other SoundTouchJS worklet packages. The formant correction logic lives in `beforePipeProcess` (LPC analysis) and `extractSamples` (analysis/synthesis filter application + `formantStrength` blend) — both hooks defined by the base class contract.

## License

MPL-2.0 — see [LICENSE](../../LICENSE) for details.
4 changes: 4 additions & 0 deletions packages/phase-vocoder-worklet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ node.addEventListener('metrics', (e) => {
| Startup latency | Lower | `fftSize` samples |
| Artifacts | Clicks / repeats | "Phasiness" / smearing |

## Architecture

`PhaseVocoderProcessor` extends `SoundTouchProcessorBase` from `@soundtouchjs/worklet-base`, sharing the DSP pipeline, runtime-update queue, and `STANDARD_PARAMETER_DESCRIPTORS` with the other SoundTouchJS worklet packages. Override `beforePipeProcess` and `extractSamples` from the base if you need to customise the processing hooks.

## License

MPL-2.0 — see [LICENSE](../../LICENSE) for details.
Loading
Loading