Skip to content

Commit

Permalink
Nodejs binding (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
albho authored Aug 15, 2024
1 parent ba0f5b6 commit 2bf0c8d
Show file tree
Hide file tree
Showing 45 changed files with 6,379 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/c.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
name: ${{ matrix.pv_speaker_platform }}
path: |
lib/${{ matrix.output_dir }}/libpv_speaker.*
lib/node/${{ matrix.output_dir }}/pv_speaker.node
retention-days: 3

build-self-hosted:
Expand Down Expand Up @@ -103,6 +104,7 @@ jobs:
name: ${{ matrix.pv_speaker_platform }}
path: |
lib/${{ matrix.output_dir }}/libpv_speaker.*
lib/node/${{ matrix.output_dir }}/pv_speaker.node
retention-days: 3

build-mac:
Expand Down Expand Up @@ -138,6 +140,7 @@ jobs:
name: ${{ matrix.pv_speaker_platform }}
path: |
lib/${{ matrix.output_dir }}/libpv_speaker.*
lib/node/${{ matrix.output_dir }}/pv_speaker.node
retention-days: 3

build-windows:
Expand Down Expand Up @@ -168,6 +171,7 @@ jobs:
name: windows
path: |
lib/windows/amd64/libpv_speaker.*
lib/node/windows/amd64/pv_speaker.node
retention-days: 3

collect-artifacts:
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/link-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Check Markdown links

on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]

jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'yes'
use-verbose-mode: 'yes'
35 changes: 35 additions & 0 deletions .github/workflows/nodejs-codestyle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Node.js Codestyle

on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- '**/nodejs/*.js'
- '**/nodejs/*.ts'
- '.github/workflows/nodejs-codestyle.yml'
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- '**/nodejs/*.js'
- '**/nodejs/*.ts'
- '.github/workflows/nodejs-codestyle.yml'

jobs:
check-nodejs-codestyle:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Set up Node.js LTS
uses: actions/setup-node@v3
with:
node-version: lts/*

- name: Pre-build dependencies
run: npm install yarn

- name: Run Binding Linter
run: yarn && yarn lint
working-directory: binding/nodejs
81 changes: 81 additions & 0 deletions .github/workflows/nodejs-demos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Node.js Demos

on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- 'demo/nodejs/**'
- '!demo/nodejs/README.md'
- '.github/workflows/nodejs-demos.yml'
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- 'demo/nodejs/**'
- '!demo/nodejs/README.md'
- '.github/workflows/nodejs-demos.yml'

defaults:
run:
working-directory: demo/nodejs

jobs:
build-github-hosted:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest]
node-version: [16.x, 18.x, 20.x]

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

# ************** REMOVE AFTER RELEASE ********************
- name: Build Node.js SDK
run: yarn && yarn build
working-directory: binding/nodejs
# ********************************************************

- name: Pre-build dependencies
run: npm install yarn

- name: Install dependencies
run: yarn install

- name: Run get audio devices
run: node demo.js --show_audio_devices

build-self-hosted:
runs-on: ${{ matrix.machine }}

strategy:
matrix:
machine: [rpi3-32, rpi3-64, rpi4-32, rpi4-64, rpi5-32, rpi5-64, pv-windows, pv-ios]

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

# ************** REMOVE AFTER RELEASE ********************
- name: Build Node.js SDK
run: yarn && yarn build
working-directory: binding/nodejs
# ********************************************************

- name: Pre-build dependencies
run: npm install yarn

- name: Install dependencies
run: yarn install

- name: Run get audio devices
run: node demo.js --show_audio_devices
104 changes: 104 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Node.js

on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- 'binding/nodejs/**'
- '!binding/nodejs/README.md'
- 'lib/node/**'
- '.github/workflows/nodejs.yml'
pull_request:
branches: [ main, 'v[0-9]+.[0-9]+' ]
paths:
- 'binding/nodejs/**'
- '!binding/nodejs/README.md'
- 'lib/node/**'
- '.github/workflows/nodejs.yml'

defaults:
run:
working-directory: binding/nodejs

jobs:
build-github-hosted:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest]
node-version: [16.x, 18.x, 20.x]

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Pre-build dependencies
run: npm install yarn

- name: Install dependencies
run: yarn install

- name: Setup build
run: yarn prepare

- name: Build
run: yarn build

# GitHub Actions runners do not have sound cards, so a virtual one must be created in order for unit tests to run.
- name: Install PulseAudio on Ubuntu
run: |
sudo apt-get update
sudo apt-get install -y pulseaudio
pulseaudio --check || pulseaudio --start
pactl load-module module-null-sink
- name: Test
run: yarn test

build-self-hosted:
runs-on: ${{ matrix.machine }}

strategy:
matrix:
machine: [rpi3-32, rpi3-64, rpi4-32, rpi4-64, rpi5-32, rpi5-64, pv-windows, pv-ios]

steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Pre-build dependencies
run: npm install yarn

- name: Install dependencies
run: yarn install

- name: Setup build
run: yarn prepare

- name: Build
run: yarn build

- name: Install PulseAudio
if: matrix.machine == 'rpi3-32' ||
matrix.machine == 'rpi3-64' ||
matrix.machine == 'rpi4-32' ||
matrix.machine == 'rpi4-64' ||
matrix.machine == 'rpi5-32' ||
matrix.machine == 'rpi5-64'
run: |
sudo apt-get update
sudo apt-get install -y pulseaudio
pulseaudio --check || pulseaudio --start
pactl load-module module-null-sink
- name: Test
run: yarn test
82 changes: 80 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<!-- markdown-link-check-disable -->
[![PyPI](https://img.shields.io/pypi/v/pvspeaker)](https://pypi.org/project/pvspeaker/)
[![npm](https://img.shields.io/npm/v/@picovoice/pvspeaker-node?label=npm%20%5Bnode%5D)](https://www.npmjs.com/package/@picovoice/pvspeaker-node)
<!-- markdown-link-check-enable -->

Made in Vancouver, Canada by [Picovoice](https://picovoice.ai)
Expand All @@ -19,9 +20,11 @@ PvSpeaker is an easy-to-use, cross-platform audio player designed for real-time
- [Source Code](#source-code)
- [Demos](#demos)
- [Python](#python-demo)
- [Node.js](#nodejs-demo)
- [C](#c-demo)
- [SDKs](#sdks)
- [Python](#python)
- [Python](#python)
- [Node.js](#nodejs)

## Source Code

Expand Down Expand Up @@ -66,6 +69,30 @@ Replace `{INPUT_WAV_PATH}` with the path to the PCM WAV file you wish to play.

For more information about the Python demos go to [demo/python](demo/python).

### Node.js Demo

Install the demo package:

```console
yarn global add @picovoice/pvspeaker-node-demo
```

To show the available audio devices run:

```console
pvspeaker-node-demo --show_audio_devices
```

With a working speaker connected to your device run the following in the terminal:

```console
pvspeaker-node-demo --input_wav_path ${INPUT_WAV_PATH}
```

Replace `{INPUT_WAV_PATH}` with the path to the `wav` file you wish to play.

For more information about Node.js demo, go to [demo/nodejs](demo/nodejs).

### C Demo

Run the following commands to build the demo app:
Expand Down Expand Up @@ -139,4 +166,55 @@ Once you are done (i.e. no longer need PvSpeaker to write and/or play PCM), free
speaker.delete()
```

For more information about the PvSpeaker Python SDK, go to [binding/python](binding/python).
For more information about the PvSpeaker Python SDK, go to [binding/python](binding/python).

### Node.js

Install Node.js binding:

```console
yarn add @picovoice/pvspeaker-node
```

To start playing audio, initialize the instance and run `start()`:

```typescript
const { PvSpeaker } = require("@picovoice/pvspeaker-node");

const sampleRate = 22050;
const bitsPerSample = 16;
const deviceIndex = 0;
const speaker = new PvSpeaker(sampleRate, bitsPerSample, { deviceIndex });

speaker.start()
```

Write frames of audio:

```typescript
function getNextAudioFrame(): ArrayBuffer {
//
}

speaker.write(getNextAudioFrame())
```

When all frames have been written, run `flush()` to wait for all buffered PCM data to be played:

```typescript
speaker.flush()
```

To stop playing audio, run `stop()`:

```typescript
speaker.stop();
```

Once you are done (i.e. no longer need PvSpeaker to write and/or play PCM), free the resources acquired by PvSpeaker by calling `release`. You do not have to call `stop` before `release`:

```typescript
speaker.release();
```

For more information about the PvSpeaker Node.js SDK, go to [binding/nodejs](binding/nodejs).
5 changes: 5 additions & 0 deletions binding/nodejs/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
lib
resources
.eslintrc.js
Loading

0 comments on commit 2bf0c8d

Please sign in to comment.