Giter Site home page Giter Site logo

clap-detector's Introduction

Clap detection module for node js

Synopsis

ClapDetector is a hand clap detection module for nodejs (iojs). It detects a clap or a series of claps and allows you to trigger callbacks whenever these events happen. I created this module for my personal assistant project on a Raspberry Pi (raspbian). The clap detection allows me to activate the assistant whenever I need it (and prevents it from continuously listening out for instructions or interpreting random noises as instructions)

Requirements

This module works on linux based OS (raspbian, Ubuntu, Debian...) using alsa for audio and a working microphone or Mac OS X using coreaudio.

Installation

This module requires sox, "the Swiss Army knife of sound processing programs" (http://sox.sourceforge.net/) to be installed

Linux

sudo apt-get install sox

Mac OS X

brew install sox

npm install

You can simply add this module to your node.js project with

npm install --save clap-detector

Usage

First, create an instance of the ClapDetector class:

const clap = new ClapDetector()

Then register a callback that will be triggered whenever a series of hand claps is detected. Your callback will be provided with an array of claps and their associated timestamps as arguments.

const disposableOneClapListener = clap.addClapsListener(claps => {
  console.log("heard 1 clap", claps)
}, { number: 1, delay: 0 })

You can dispose (remove) a clap listener by calling the disposable method returned by addClapsListeners

disposableOneClapListener() // dispose the clap listener

Finally you can call the dispose() method when you want to stop all clap detection and free associated resources

clap.dispose()

addClapsListener

  • Type : Function
  • Arguments: (callback [Function], options [Object])
list of options
Option Description Default value
number Number of claps 1
delay Period within the specified number of claps must be heard (ms) 1000
force If true, trigger callback every time even if a listener with a higher number is triggered false

Real life example

import ClapDetector from 'clap-detector'

const clap = new ClapDetector()

clap.addClapsListener(claps => {
  console.log("change tv channel")
}, { number: 1, delay: 0 })

clap.addClapsListener(claps => {
  console.log("turn tv on", claps)
}, { number: 2, delay: 1000 })

clap.addClapsListener(claps => {
  console.log("turn tv off", claps)
}, { number: 3, delay: 1000 })

Full example

import ClapDetector from 'clap-detector'

const clap = new ClapDetector()
const disposableOneClapListener = clap.addClapsListener(claps => {
  console.log("heard 1 clap (force)", claps)
}, { number: 1, delay: 0, force: true })

const disposableOneClapForceListener = clap.addClapsListener(claps => {
  console.log("heard 1 clap", claps)
}, { number: 1, delay: 1000 })

const disposableTwoClapsListener = clap.addClapsListener(claps => {
  console.log("heard 2 claps", claps)
}, { number: 2, delay: 1000 })

const disposableThreeClapsListener = clap.addClapsListener(claps => {
  console.log("heard 3 claps", claps)
}, { number: 3, delay: 1000 })

// Cancel some clap listeners
// Cancel alls claps listener but 2 claps after 10 seconds
setTimeout(() => {
  console.log("only listen to 2 claps now")
  disposableOneClapListener()
  disposableOneClapForceListener()
  disposableThreeClapsListener()
}, 10000)

// Dispose (stop sox process and listeners) after 30s
setTimeout(() => {
  console.log("dispose all listeners and free ressources")
  clap.dispose()
}, 30000)

Configuration

You can pass a configuration object and override the default values when you create an instance of the ClapDetector class. If you don't the following config will be used.

// DEFAULT CONFIG
var CONFIG = {
  AUDIO_SOURCE: 'hw:1,0', // this is your microphone input. If you dont know it you can refer to this thread (http://www.voxforge.org/home/docs/faq/faq/linux-how-to-determine-your-audio-cards-or-usb-mics-maximum-sampling-rate)
  DETECTION_PERCENTAGE_START : '5%', // minimum noise percentage threshold necessary to start recording sound
  DETECTION_PERCENTAGE_END: '5%',  // minimum noise percentage threshold necessary to stop recording sound
  CLAP_AMPLITUDE_THRESHOLD: 0.7, // minimum amplitude threshold to be considered as clap
  CLAP_ENERGY_THRESHOLD: 0.3,  // maximum energy threshold to be considered as clap
  MAX_HISTORY_LENGTH: 10 // all claps are stored in history, this is its max length
}
const clap = new ClapDetector(CONFIG)

If you wish to improve the clap detection you can fiddle with the CLAP_AMPLITUDE_THRESHOLD and CLAP_ENERGY_THRESHOLD values. Depending on your microphone these might need to be modified.

Tests

These will be added soon. Please do not hesitate to submit some Ò!

About the Author

I am a full-stack Javascript developer based in Lyon, France.

Check out my website

License

clap-detector is dual licensed under the MIT license and GPL. For more information click here.

clap-detector's People

Contributors

anaibol avatar anttilaiti avatar cem2ran avatar dependabot[bot] avatar gauthier-th avatar laiti avatar nickmomrik avatar tom-s avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

clap-detector's Issues

OSX input source

I was looking the module, very nice, I was wondering if you know which could be the input device config for the built-in mic.

greetings

add max delta check

it seems to be more precise if i add Maximum delta > 0.5 to the isClap method (i had it trigger more or less randomly while listening to music)

[Noob Question] Can't import ClapDetector from 'clap-detector'

Hi,

I try to use jour Libary, but I'm realy new to node js.
So maybe this is a normal beginner question, but I don't found anything on "google" that matches my problem.

I use a Raspberry Pi 4 with a USB-Micro. I use the normal Raspberry Pi console os.

I have then update the OS and have done the folling steps:

sudo apt-get update ; sudo apt-get update -y ; sudo apt-get install sox;
sudo apt-get install nodejs npm
curl https://www.npmjs.com/install.sh | sudo sh
mkdir new_clap_npm; cd new_clap_npm;
npm install --save clap-detector
touch clap.js

This creates the folling in new_clap_npm:
drwxr-xr-x 3 pi pi 4096 Jul 21 12:46 . drwxr-xr-x 11 pi pi 4096 Jul 21 12:43 .. -rw-r--r-- 1 pi pi 1067 Jul 21 12:47 clap.js drwxr-xr-x 5 pi pi 4096 Jul 21 12:45 node_modules -rw-r--r-- 1 pi pi 58 Jul 21 12:45 package.json -rw-r--r-- 1 pi pi 1888 Jul 21 12:45 package-lock.json

I have then copy this into clap.js:

`import ClapDetector from 'clap-detector'

const clap = new ClapDetector()
const disposableOneClapListener = clap.addClapsListener(claps => {
console.log("heard 1 clap (force)", claps)
}, { number: 1, delay: 0, force: true })

const disposableOneClapForceListener = clap.addClapsListener(claps => {
console.log("heard 1 clap", claps)
}, { number: 1, delay: 1000 })

const disposableTwoClapsListener = clap.addClapsListener(claps => {
console.log("heard 2 claps", claps)
}, { number: 2, delay: 1000 })

const disposableThreeClapsListener = clap.addClapsListener(claps => {
console.log("heard 3 claps", claps)
}, { number: 3, delay: 1000 })

// Cancel some clap listeners
// Cancel alls claps listener but 2 claps after 10 seconds
setTimeout(() => {
console.log("only listen to 2 claps now")
disposableOneClapListener()
disposableOneClapForceListener()
disposableThreeClapsListener()
}, 10000)

// Dispose (stop sox process and listeners) after 30s
setTimeout(() => {
console.log("dispose all listeners and free ressources")
clap.dispose()
}, 30000)
`

If I try now to start with: I get
`/home/pi/new_clap_npm/clap.js:1
import ClapDetector from 'clap-detector'
^^^^^^^^^^^^

SyntaxError: Unexpected identifier
at Module._compile (internal/modules/cjs/loader.js:723:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)`

Viso shows me this error on line 1:
Could not find a declaration file for module 'clap-detector'. '/home/pi/new_clap_npm/node_modules/clap-detector/lib/index.js' implicitly has an 'any' type. Try npm i --save-dev @types/clap-detectorif it exists or add a new declaration (.d.ts) file containingdeclare module 'clap-detector';ts(7016) module "/home/pi/new_clap_npm/node_modules/clap-detector/lib/index"

If I try to do the Viso fix I get:
`pi@raspberrypi:~/new_clap_npm $ npm i --save-dev @types/clap-detector
npm ERR! code E404
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@types%2fclap-detector - Not found
npm ERR! 404
npm ERR! 404 '@types/clap-detector@*' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.

npm ERR! A complete log of this run can be found in:
npm ERR! /home/pi/.npm/_logs/2021-07-21T11_06_57_973Z-debug.log`

Please help me to import your libary.

Best regards

Sox can't process the arguments given by clap-detector

I've logged the cmd that is executed using sox and entered into the command line:

user@server:~/scripts $ sox -t hw:0,0 /home/user/input.wav silence 1 0.0001 10% 1 0.1 10% −−no−show−progress stat
sox:      SoX v14.4.2

sox FAIL sox: Not enough input filenames specified

Usage summary: [gopts] [[fopts] infile]... [fopts] outfile [effect [effopt]]...
...

Maybe sox has been changed in the mean time?

Unfortunately this command isn't working. The output of arecord is:

user@server:~/scripts $ arecord --list-devices
**** List of CAPTURE Hardware Devices ****
card 0: U0x41e0x30d3 [USB Device 0x41e:0x30d3], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Does not handle muptilple claps well

Clap-detector does detect multiple claps accurately, but it fails to process them properly.
I've set it to turn the screen off on 2 claps and turn it back on on 3 claps.
It doesn't work. The claps overlap, and it only does turn the screen off.
The script calls the shell script as soon as there've been two claps, not waiting for more. That means, if one sets up 2, 3, 4, and 5 clap handlers and claps 5 times, all of them will be triggered.
What's more, if I clap 3 times, it's detected as 1 sequence of three claps and 2 sequences of 2 claps.

detected sound
Clap detected:  [ { id: 1, time: 1546043724202 } ]
detected sound
Clap detected:  [ { id: 1, time: 1546043724202 },
  { id: 2, time: 1546043724763 } ]
2 claps detected. Screen off
detected sound
Clap detected:  [ { id: 1, time: 1546043724202 },
  { id: 2, time: 1546043724763 },
  { id: 3, time: 1546043725286 } ]
3 claps detected. Screen on
2 claps detected. Screen off

If I remove the 3 claps handler, the 2 claps handler is still triggered twice on three claps:

Clap detected:  [ { id: 1, time: 1546043865102 } ]
detected sound
Clap detected:  [ { id: 1, time: 1546043865102 },
  { id: 2, time: 1546043865662 } ]
2 claps detected. Screen off
detected sound
Clap detected:  [ { id: 1, time: 1546043865102 },
  { id: 2, time: 1546043865662 },
  { id: 3, time: 1546043866276 } ]
2 claps detected. Screen off

Version 0.5.0 is broken

Attempting to install the newest version and run the example given in the readme leads to this error:

internal/modules/cjs/loader.js:583
    throw err;
    ^

Error: Cannot find module 'lodash/uniqueid'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
    at Function.Module._load (internal/modules/cjs/loader.js:507:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (/home/[redacted]/node_modules/clap-detector/lib/index.js:26:40)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

The reason for the error is that on line 36 of index.js the module is imported from 'lodash/uniqueid' instead of 'lodash/uniqueId' (note the capitalization).

Problems using your demo example

Dear tom-s,

I tried copying you "full example" into a .js file i called test-clap.js and tried running it but get the following error message. I also changed the first line from "import ClapDetector from 'clap-detector'" to "const ClapDetector = require('clap-detector')". I am new to node and hope this is a beginner mistake.

~/watson/test-clap $ sudo node test-clap.js
/home/watson/watson/test-clap/test-clap.js:4
const clap = new ClapDetector()
^

TypeError: ClapDetector is not a constructor
at Object. (/home/watson/watson/test-clap/test-clap.js:4:14)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Module.load (internal/modules/cjs/loader.js:566:32)
at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
at Function.Module._load (internal/modules/cjs/loader.js:498:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:695:10)
at startup (internal/bootstrap/node.js:201:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)

the node_modules folder is in the same directory as ~/watson
I am running node version v9.11.2
strangely, it works when running your demo program as follows:
sudo node node_modules/clap-detector/lib/demo.js

MAXBUFFER Error

Hi.
I've met this error on using your module.

{ RangeError [ERR_CHILD_PROCESS_STDIO_MAXBUFFER]: stderr maxBuffer length exceeded
    at Socket.onChildStderr (child_process.js:374:14)
    at Socket.emit (events.js:187:15)
    at addChunk (_stream_readable.js:279:12)
    at readableAddChunk (_stream_readable.js:260:13)
    at Socket.Readable.push (_stream_readable.js:219:10)
    at Pipe.onread (net.js:636:20)
  cmd:
   'sox -t coreaudio default /SOME_PATH/input.wav silence 1 0.0001 5% 1 0.1 5% −−no−show−progress stat' }

Used codes are like this;

    this.detector = new ClapDetector(config)

    this.detector.addClapsListener((claps) => {
       console.log(claps)
    }, {number:1, delay:0, force:true})

I executed the code and did nothing. Just waiting. After several minutes, that error occurs.

Microphone for Raspberry Pi 3

Hello!
This project seems interesting.
Can I use it in my Raspberry Pi 3? Do you recommend me any USB microphone? (I don't want to use my GPIO ports, already used).
Thanks a lot.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.