I'm seeing this was posted a year ago here, so felt best to post a new question with an updated module.
Following the docs here, I created a react component to detect wake words using a custom "Yo Llama" wake word. It was trained and downloaded as a web/WASM ppn file, which is also reflected in the name when it downloaded, Yo-Llama_en_wasm_v3_0_0.ppn
.
I placed this and the model file in my React public/picovoice/
folder. I can confirm that I could access/download these files at:
http://localhost:5173/picovoice/Yo-Llama_en_wasm_v3_0_0.ppn
http://localhost:5173/picovoice/porcupine_params.pv
When I launch my local React app, I see this error immediately:
Initialization failed: [0] Keyword file (.ppn) file has incorrect format or belongs to a different platform. [1] Picovoice Error (code `00000136`) [2] Loading keyword file at `Yo Llama` failed with `INVALID_ARGUMENT`.
This doesn't seem right. I've seen a couple of other similar posts with a check that the file is in the right place and format answers (1, 2), yet these didn't seem to be responded to by the posters as resolved. This could be the case, yet I'm paying attention to the details so far.
To double check that I was downloading the right format, I tried to train another model on the picovoice website, yet I've hit my limit of one trained keyword for the month.
import React, { useEffect, useState } from 'react';
import { usePorcupine } from '@picovoice/porcupine-react';
import { Box, FormControlLabel, Switch, Alert } from '@mui/material';
const VoiceWidget = () => {
const [initAttempted, setInitAttempted] = useState(false);
const {
keywordDetection,
isLoaded,
isListening,
error,
init,
start,
stop,
release,
} = usePorcupine();
const porcupineKeyword = {
publicPath: '/picovoice/Yo-Llama_en_wasm_v3_0_0.ppn',
label: 'Yo Llama',
};
const porcupineModel = {
publicPath: '/picovoice/porcupine_params.pv',
};
const handleToggleListen = async (
event: React.ChangeEvent<HTMLInputElement>
) => {
try {
if (event.target.checked) {
console.log('Starting voice detection...');
await start();
} else {
console.log('Stopping voice detection...');
await stop();
}
} catch (err) {
console.error('Error toggling voice detection:', err);
}
};
useEffect(() => {
const initializePorcupine = async () => {
try {
// TODO: Move this key away from react/public, perhaps get with authed server config respnose
const TEMP_ACCESS_KEY =
'REDACTED';
console.log('Initializing Porcupine with paths:', {
keyword: porcupineKeyword.publicPath,
model: porcupineModel.publicPath,
});
await init(TEMP_ACCESS_KEY, porcupineKeyword, porcupineModel);
setInitAttempted(true);
} catch (err) {
console.error('Porcupine initialization error:', err);
setInitAttempted(true);
}
};
initializePorcupine();
// Cleanup on unmount
return () => {
release();
};
}, []);
useEffect(() => {
if (keywordDetection !== null) {
console.log('Keyword detected:', {
index: keywordDetection.index,
label: keywordDetection.label,
});
}
}, [keywordDetection]);
return (
<Box sx={{ p: 2 }}>
{error && (
<Alert severity="error" sx={{ mb: 2 }}>
{error.message}
</Alert>
)}
<Box sx={{ mb: 1 }}>
Status:{' '}
{!initAttempted
? 'Initializing...'
: isLoaded
? 'Ready'
: 'Failed to initialize'}
</Box>
<Box sx={{ mb: 1 }}>Listening: {isListening ? 'Yes' : 'No'}</Box>
<FormControlLabel
control={
<Switch
onChange={handleToggleListen}
disabled={!isLoaded}
checked={isListening}
/>
}
label="Listen for wake word"
/>
</Box>
);
};
export default VoiceWidget;
Here's the modules/versions used:
"@picovoice/porcupine-react": "^3.0.3",
"@picovoice/web-voice-processor": "^4.0.9",
Would you have any ideas of what I could be missing to get this to work?