{"id":23480556,"url":"https://github.com/givimad/rustpotter-cli","last_synced_at":"2025-04-14T22:55:11.957Z","repository":{"id":40385898,"uuid":"477333008","full_name":"GiviMAD/rustpotter-cli","owner":"GiviMAD","description":"Command line utility for rustpotter, an open source wakeword spotter forged in rust","archived":false,"fork":false,"pushed_at":"2023-10-07T14:50:05.000Z","size":303,"stargazers_count":15,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-14T22:54:58.734Z","etag":null,"topics":["cli","command-line","keyword-extraction","keyword-spotting","wakeword","wakeword-activation"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GiviMAD.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-04-03T12:20:44.000Z","updated_at":"2025-03-10T22:42:46.000Z","dependencies_parsed_at":"2023-01-30T22:30:30.032Z","dependency_job_id":null,"html_url":"https://github.com/GiviMAD/rustpotter-cli","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GiviMAD%2Frustpotter-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GiviMAD%2Frustpotter-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GiviMAD%2Frustpotter-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GiviMAD%2Frustpotter-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GiviMAD","download_url":"https://codeload.github.com/GiviMAD/rustpotter-cli/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975330,"owners_count":21192208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","command-line","keyword-extraction","keyword-spotting","wakeword","wakeword-activation"],"created_at":"2024-12-24T20:16:50.632Z","updated_at":"2025-04-14T22:55:11.934Z","avatar_url":"https://github.com/GiviMAD.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rustpotter CLI\n\nCLI for Rustpotter, an open source wakeword spotter forged in rust\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg src=\"./logo.png?raw=true\" width=\"400px\"\u003c/img\u003e \n\u003c/div\u003e\n\n## Description\n\nThis is a client for using the [rustpotter](https://github.com/GiviMAD/rustpotter) library on the command line.\n\nYou can use it to record wav samples, create rustpotter wakeword files and test them.\n\n# Installation\n\nSome pre-build executables for the supported platforms can be found on the 'Assets' tab of the [releases](https://github.com/GiviMAD/rustpotter-cli/releases).\n\n# Basic usage.\n\n## Listing available audio input devices and formats.\n\nYour can list the available audio sources with the `devices` command,\nthe `--configs` option can be added to display the default and available record formats for each source.\n\nEvery device and config has a numerical id to the left which is the one you can use on the other commands (`record` and `spot`)\nto change its audio source and format.\n\nIn some systems to many configurations are displayed you can filter them by max channel number using the parameter `--max-channels`.\n\nThis is an example run on macOS:\n\n```bash\n$ rustpotter-cli devices -c -m 1\nAudio hosts:\n  - CoreAudio\nDefault input device:\n  - MacBook Pro Microphone\nAvailable Devices: \n0 - MacBook Pro Microphone\n  Default input stream config:\n      - Sample Rate: 48000, Channels: 1, Format: f32, Supported: true\n  All supported input stream configs:\n    0 - Sample Rate: 44100, Channels: 1, Format: f32, Supported: true\n    1 - Sample Rate: 48000, Channels: 1, Format: f32, Supported: true\n    2 - Sample Rate: 88200, Channels: 1, Format: f32, Supported: true\n    3 - Sample Rate: 96000, Channels: 1, Format: f32, Supported: true\n```\n\n## Recording audio samples\n\nThe `record` command allows to record audio samples.\nTo use a different input device provide the  `--device-index` argument with the id returned by the `devices` commands. \nYou pass the configuration id returned by the `devices` commands using the `--config-index` option to change the audio format.\nOnce executed you need to press the `Ctrl + c` key combination to finish the record.\n\nThis is an example run on macOS:\n\n```bash\n$ rustpotter-cli record good_morning.wav\nInput device: MacBook Pro Microphone\nInput device config: Sample Rate: 48000, Channels: 1, Format: f32\nBegin recording...\nPress 'Ctrl + c' to stop.\n^CRecording good_morning.wav complete!\n```\n\nYou can use something like this in bash to take multiple records quickly:\n\n```bash\nWAKEWORD=\"ok home\"\nWAKEWORD_FILENAME=\"${WAKEWORD// /_}\"\n# take 10 records, waiting one second after each.\nfor i in {0..9}; do (rustpotter-cli record $WAKEWORD_FILENAME$i.wav \u0026\u0026 sleep 1); done\n```\n\n## Creating a Wakeword Model\n\nThe `train` command allows to create wakeword models.\n\nIt's required to setup a training and testing folders containing wav records which need to be tagged (contains [label] in its file name, where 'label' is the tag the network should predict for that audio segment) or untagged (equivalent to contain [none] on the filename).\nThe tag `none` is reserved because it will not emit a detections, but doesn't need to be added to the filenames.\n\nThe size and cpu usage of a wakeword model is based on the model type you choose, and the audio duration it was trained on (which is defined by the max audio duration found on the training set) and the number of labels in the training set. The train command prints these information at the beginning.\n\nExample train directory (truncated output):\n\n```bash\n$ ls train\n'[ok_home]11.wav'                         building112.wav   kitchen21.wav    kitchen489.wav   kitchen91.wav   room98.wav\n'[ok_home]12.wav'                         building113.wav   kitchen210.wav   kitchen49.wav    kitchen92.wav   room99.wav\n'[ok_home]13.wav'                         building114.wav   kitchen211.wav   kitchen490.wav   kitchen93.wav   speaker0.wav\n'[ok_home]14.wav'                         building115.wav   kitchen212.wav   kitchen491.wav   kitchen94.wav   speaker1.wav\n'[ok_home]15.wav'                         building116.wav   kitchen213.wav   kitchen492.wav   kitchen95.wav   speaker10.wav\n'[ok_home]16.wav'                         building117.wav   kitchen214.wav   kitchen493.wav   kitchen96.wav   speaker100.wav\n'[ok_home]1692561880432.wav'              building118.wav   kitchen215.wav   kitchen494.wav   kitchen97.wav   speaker101.wav\n...\n```\n\nThose will train a model to spot \"ok_home\". These dataset includes about 250 records of the wakeword (the records prefixed by \"[ok_home]\") and about 1800 records of noises or silence, as you can see I have named those depending on what or where I was recording, but that doesn't matter as long as they do not include the delimiters \"[\" and \"]\" those are threated as if they include \"[none]\".\n\nThe files in the test folder should follow same rules. In this case it contains 41 records of the wakeword and around 78 random records.\n\nIt's recommended to have records of the same duration in both folders, if not the data will be truncated or padded with silence  by the max record duration on the train folder (this happens in-memory, it does not modifies the files).\n\nExample run:\n\n```sh\n$ rustpotter-cli train -t small --train-dir train.wav/train --test-dir train.wav/test --test-epochs 10 --epochs 2500 -l 0.017 trained-small.rpw \nStart training trained-small.rpw!\nModel type: small.\nLabels: [\"none\", \"ok_casa\"].\nTraining with 2042 records.\nTesting with 119 records.\nTraining on 1950ms of audio.\n  10 train loss:  0.12944 test acc: 90.76%\n  20 train loss:  0.06484 test acc: 93.28%\n  30 train loss:  0.04454 test acc: 94.12%\n  40 train loss:  0.03361 test acc: 94.12%\n  50 train loss:  0.02687 test acc: 94.12%\n  60 train loss:  0.02227 test acc: 94.12%\n  70 train loss:  0.01916 test acc: 94.12%\n  80 train loss:  0.01681 test acc: 94.12%\n  90 train loss:  0.01499 test acc: 94.12%\n 100 train loss:  0.01354 test acc: 94.12%\n 110 train loss:  0.01232 test acc: 94.96%\n...  \n 160 train loss:  0.00822 test acc: 94.96%\n 170 train loss:  0.00766 test acc: 94.96%\n 180 train loss:  0.00717 test acc: 95.80%\n 190 train loss:  0.00673 test acc: 95.80%\n...\n 470 train loss:  0.00234 test acc: 95.80%\n 480 train loss:  0.00229 test acc: 95.80%\n 490 train loss:  0.00224 test acc: 96.64%\n 500 train loss:  0.00219 test acc: 96.64%\n...\n1180 train loss:  0.00083 test acc: 96.64%\n1190 train loss:  0.00082 test acc: 96.64%\n1200 train loss:  0.00081 test acc: 97.48%\n1210 train loss:  0.00081 test acc: 97.48%\n...\n2340 train loss:  0.00034 test acc: 97.48%\n2350 train loss:  0.00034 test acc: 97.48%\n2360 train loss:  0.00034 test acc: 98.32%\n2370 train loss:  0.00033 test acc: 98.32%\n...\n2480 train loss:  0.00031 test acc: 98.32%\n2490 train loss:  0.00031 test acc: 98.32%\n2500 train loss:  0.00031 test acc: 98.32%\ntrained-small.rpw created!\n```\n\nBe aware that you can obtain different results on different executions with the same training set as the initialization of the weights is not constant.\n\nYou can continue training from another model using the `-m` option, in that case the options used to create that model (and the audio duration) are used instead.\n\nTo get a correct idea about the accuracy of the model, do not share records between the train and test folders.\n\nOne last tip, you can take advantage of the`spot` command option for creating records on partial spot, it's an easy way to record samples.\nFor example creating a wakeword reference to use for capturing records for later training a wakeword model,\nbut also it's a great way of capturing records of false positives detected by a wakeword model, which are very valuable for training a better version.\n\n## Creating a Wakeword Reference\n\nThe `build` command allows to create a wakeword reference file from some records.\n\nThis wakeword type requires a low number of records to be created but offers more inconsistent results than the wakeword models. \n\nAs an example example:\n\n```\nrustpotter-cli build --model-name \"ok home\" --model-path ok_home.rpw ok_home1.wav ok_home2.wav\n```\n\nThis is an example run on macOS:\n\n```bash\n$ WAKEWORD=\"ok home\"\n$ WAKEWORD_FILENAME=\"${WAKEWORD// /_}\"\n$ rustpotter-cli build --model-name \"$WAKEWORD\" --model-path $WAKEWORD_FILENAME.rpw $WAKEWORD_FILENAME*.wav\nok_home1.wav: WavSpec { channels: 2, sample_rate: 44100, bits_per_sample: 32, sample_format: Float }\nok home created!\n```\n\n## Using a model\n\nYou can use the commands `spot` to test a model in real time using the available audio inputs,\nor `test` to do it against an audio file.\nBoth expose similar options to make change from one to the other simpler.\n\nThis way you can record an example record and tune the options there to then test those on real time. \n\nThis is an example run on macOS:\n```bash\n$ rustpotter-cli test -g --gain-ref 0.004 ok_home_test.rpw test_audio.wav\nTesting file test_audio.wav against model ok_home_test.rpw!\nWakeword detection: [11:06:11] RustpotterDetection { name: \"ok_home_test\", avg_score: 0.0, score: 0.5261932, scores: {\"ok_home1-bandpass1000_2000.wav\": 0.5261932}, counter: 12, gain: 0.9 }\n```\n\nThe more relevant options for the `spot` and `test` commands are:\n\n* `-d` parameter enables the called 'debug mode' so you can see the partial detections.\n* `-t` sets the threshold value (defaults to 0.5).\n* `-m 6` require at least 6 frames of positive scoring (compared against the detection `counter` field).\n* `-e` enables the eager mode so detection is emitted as soon as possible (on min positive scores).\n* `-g` enables gain normalization. To debug the gain normalization you can use `--debug-gain`, or look at the gain reflected on the detection.\n* `--gain-ref` changes the gain normalization reference. (the default value is printed at the beginning when `--debug-gain` is provided, depends on the wakeword)\n\n### Record on Partial Detections\n\nRustpotter can create audio records every partial detection, this can be useful to collect samples or to debug the behavior of the library.\n\nThis can be enabled by providing a folder path to the `spot` or `test` commands in the `--record-path` option.\nThe folder must exists and be writable for the records to be created.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgivimad%2Frustpotter-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgivimad%2Frustpotter-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgivimad%2Frustpotter-cli/lists"}