Using the node-red-contrib-personal-wake-word node

Hello All,

I'm using this node along with the @kevingodell/node-red-ffmpeg node to create a compatible audio stream from my mic to feed into it. The issue is that I'm not sure I'm configuring the wake word setup correctly. I wanted to ask if there is anyone here who has had experience using this node? (especially preparing the wake-word audio files). I tried to record a couple of clear samples of my saying "Hey Computer" but it doesn't seem to recognize them.

The node is based on the node-personal-wakeword library. Does anyone know if there are any tools to help make the wakeword audio samples?

Here's the portion of my flow that I made for testing this node:

[
    {
        "id": "f38c430b8da6b413",
        "type": "wake-word",
        "z": "c5d098062cd1c674",
        "wakeword": "78bc3731a6c83c3e",
        "threshold": "0.04",
        "averaging": false,
        "inputProp": "payload",
        "outputProp": "payload",
        "controlProp": "control",
        "passthrough": true,
        "name": "",
        "x": 600,
        "y": 100,
        "wires": [
            [
                "569e849b6e27d696"
            ],
            []
        ]
    },
    {
        "id": "9ae7bd2136af36a9",
        "type": "ffmpeg",
        "z": "c5d098062cd1c674",
        "name": "Microphone Stream",
        "outputs": 2,
        "cmdPath": "ffmpeg",
        "cmdArgs": "[\"-f\",\"dshow\",\"-i\",\"audio=Microphone (Realtek(R) Audio)\",\"-map\",\"0\",\"-acodec\",\"pcm_s16le\",\"-ac\",\"1\",\"-ar\",\"16000\",\"-f\",\"wav\",\"pipe:1\"]",
        "cmdOutputs": 1,
        "killSignal": "SIGTERM",
        "x": 370,
        "y": 100,
        "wires": [
            [],
            [
                "f38c430b8da6b413"
            ]
        ]
    },
    {
        "id": "f3434123ecca60d9",
        "type": "inject",
        "z": "c5d098062cd1c674",
        "name": "Start",
        "props": [
            {
                "p": "action.command",
                "v": "start",
                "vt": "str"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 110,
        "y": 100,
        "wires": [
            [
                "9ae7bd2136af36a9"
            ]
        ]
    },
    {
        "id": "6abef099c6a87941",
        "type": "inject",
        "z": "c5d098062cd1c674",
        "name": "Stop",
        "props": [
            {
                "p": "action.command",
                "v": "stop",
                "vt": "str"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 110,
        "y": 140,
        "wires": [
            [
                "9ae7bd2136af36a9"
            ]
        ]
    },
    {
        "id": "9f956efc08de4580",
        "type": "udp in",
        "z": "c5d098062cd1c674",
        "name": "",
        "iface": "",
        "port": "5850",
        "ipv": "udp4",
        "multicast": "false",
        "group": "",
        "datatype": "buffer",
        "x": 340,
        "y": 320,
        "wires": [
            [
                "5d4249895ae582b9"
            ]
        ]
    },
    {
        "id": "5d4249895ae582b9",
        "type": "function",
        "z": "c5d098062cd1c674",
        "name": "Append Data",
        "func": "function appendBuffers(buffer1, buffer2) {\n    // Check if the destination buffer is empty.\n    if (!buffer1.length) {\n        return Buffer.from(buffer2);\n    }\n\n    // Check if the source buffer is empty.\n    if (!buffer2.length) {\n        return Buffer.from(buffer1);\n    }\n\n    // Concatenate the buffers into a new buffer.\n    const concatenatedBuffer = Buffer.concat([buffer1, buffer2]);\n\n    return concatenatedBuffer;\n}\n\nlet dataBuffer = context.get(\"dataBuffer\") || Buffer.from([]);\nlet resultBuffer = appendBuffers(dataBuffer, msg.payload);\n\nif (resultBuffer.length >= 32767 * 4) {\n    msg.payload = resultBuffer;\n    context.set(\"dataBuffer\", Buffer.from([]));\n    return msg;\n} else {\n    context.set(\"dataBuffer\", resultBuffer);\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 510,
        "y": 320,
        "wires": [
            [
                "e00611ad7b5f1d06"
            ]
        ]
    },
    {
        "id": "569e849b6e27d696",
        "type": "debug",
        "z": "c5d098062cd1c674",
        "name": "debug 34",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 780,
        "y": 100,
        "wires": []
    },
    {
        "id": "60a0c66471142669",
        "type": "inject",
        "z": "c5d098062cd1c674",
        "name": "listen",
        "props": [
            {
                "p": "control",
                "v": "listen",
                "vt": "str"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 410,
        "y": 160,
        "wires": [
            [
                "f38c430b8da6b413"
            ]
        ]
    },
    {
        "id": "d34a11495c92ad9d",
        "type": "inject",
        "z": "c5d098062cd1c674",
        "name": "stop",
        "props": [
            {
                "p": "control",
                "v": "stop",
                "vt": "str"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 410,
        "y": 200,
        "wires": [
            [
                "f38c430b8da6b413"
            ]
        ]
    },
    {
        "id": "e00611ad7b5f1d06",
        "type": "debug",
        "z": "c5d098062cd1c674",
        "name": "debug 35",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 700,
        "y": 320,
        "wires": []
    },
    {
        "id": "78bc3731a6c83c3e",
        "type": "wakeword-config",
        "name": "",
        "files": [
            "C:\\\\Users\\\\Jason\\\\.node-red\\\\wake-words"
        ]
    }
]

Any feedback and/or pointers greatly appreciated!

If you click on the node and open the 'Help' in the side bar and then click the 'wakeword-config` you will get information about creating the wake word:

Note: the node hasn't been updated three years and the author has not been seen on GItHub since 2021 so I would assume it has been abandoned.

Thanks, I currently have a path to the directory containing my .wav audio samples setup in the configuration node:

Knowing that this node has likely been abandoned. Would you happen to know if any alternatives that people are using nowadays? (Or if not a node, a library that I could implement in a function node or something). I'm just look for the simplest way to go about doing this.

Sorry but no I don't. HOWEVER a search of the forum found these threads that might be useful:

The author might respond...

v

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.