diff --git a/README.md b/README.md index e421758..535af8c 100644 --- a/README.md +++ b/README.md @@ -47,85 +47,7 @@ A python package for clap detection ( Try 2 claps to activate the output line for 1 sec and 3 claps to toggle ON/OFF state of given PIN. Note: Use 4 claps to exit from the system ) -### Installing dependencies for other operating systems - -``` -# Debian based OS like Ubuntu - -sudo apt-get install -y python3-pip portaudio19-dev - -``` - -``` -# Fedora - -sudo dnf install -y python3-pip portaudio-devel redhat-rpm-config -pip3 install --user pyaudio - -``` - -``` -# Centos - -sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm # CentOS 8 -rpm -Uvh https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm # CentOS 7 -rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm # CentOS 6 - -sudo yum install -y python37-pip portaudio portaudio-devel -pip3 install pyaudio -``` - -``` -# MacOS - -brew install portaudio -pip3 install pyaudio munch || pip3 install --global-option='build_ext' --global-option='-I/usr/local/include' --global-option='-L/usr/local/lib' pyaudio munch -``` - -### Example code - -``` -# Example code for using the package - -from piclap import Listener, Settings - - -class Config(Settings): - '''This is an user defined derived class with `piclap.Settings` as base class''' - - def __init__(self): - '''Defines new and override existing properties here''' - self.chunk_size = 512 # Reduce as power of 2 if pyaudio overflow - self.interval = 0.5 # Adjust interval between claps - self.method.value = 300 # Threshold value adjustment - - def on2Claps(self): - '''Custom action for 2 claps''' - print("Light flashed on pin", 4) - - def on3Claps(self): - '''Custom action for 3 claps''' - print("Light toggled on pin", 6) - -config = Config() -listener = Listener(config) -listener.start() - -``` - -### Using Pip package - -``` -# Using the following command in terminal -pip3 install pi-clap -``` - -### Using Git Clone -``` -git clone https://github.com/nikhiljohn10/pi-clap -cd pi-clap -python3 ./example/app.py -``` +##### Visit Official documentation @ [pi-clap.nikz.in](https://pi-clap.nikz.in/getting-started.html) ### License diff --git a/docs/.buildinfo b/docs/.buildinfo index 76eab5d..4624803 100644 --- a/docs/.buildinfo +++ b/docs/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 3170068174795e34d5b5a5d41032d3be +config: 7aea4f226f698ea442cec4a461fc4fe6 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_modules/index.html b/docs/_modules/index.html index 30df86a..7377a61 100644 --- a/docs/_modules/index.html +++ b/docs/_modules/index.html @@ -7,7 +7,7 @@ - Overview: module code — Pi Clap 1.3 documentation + Overview: module code — Pi Clap 1.3.1 documentation diff --git a/docs/_modules/piclap/_listener.html b/docs/_modules/piclap/_listener.html index 1752032..ec6946e 100644 --- a/docs/_modules/piclap/_listener.html +++ b/docs/_modules/piclap/_listener.html @@ -7,7 +7,7 @@ - piclap._listener — Pi Clap 1.3 documentation + piclap._listener — Pi Clap 1.3.1 documentation diff --git a/docs/_modules/piclap/_processor.html b/docs/_modules/piclap/_processor.html index aefd187..0ebb1a3 100644 --- a/docs/_modules/piclap/_processor.html +++ b/docs/_modules/piclap/_processor.html @@ -7,7 +7,7 @@ - piclap._processor — Pi Clap 1.3 documentation + piclap._processor — Pi Clap 1.3.1 documentation diff --git a/docs/_modules/piclap/_settings.html b/docs/_modules/piclap/_settings.html index 048d31d..461a2c0 100644 --- a/docs/_modules/piclap/_settings.html +++ b/docs/_modules/piclap/_settings.html @@ -7,7 +7,7 @@ - piclap._settings — Pi Clap 1.3 documentation + piclap._settings — Pi Clap 1.3.1 documentation @@ -166,28 +166,22 @@

Source code for piclap._settings

 
 
 
[docs]class Settings: - """This class describes all the configurations needed for the :class:`piclap.Listener` to work. - - :param controller: A :class:`piclap.Controller` object, defaults to None - :type controller: class: `piclap.Controller` - :var controller: Holds the controller object passed as argument - :vartype controller: class: `piclap.Controller` - :var boolean exit: Holds the controller object passed as argument - :var int rate: Holds the controller object passed as argument - :var int channels: Holds the controller object passed as argument - :var int chunk_size: Holds the controller object passed as argument - :var float interval: Holds the controller object passed as argument - - :var method: Holds the controller object passed as argument - :vartype method: class: `piclap.Controller` - :var actions: Holds the controller object passed as argument - :vartype actions: class: `piclap.Controller` + """This class describes all the configurations needed for the :class:`Listener` to work. + + :var boolean exit: Exit flag the determine the exit state of :class:`Listener` + :var int rate: Bitrate at which input audio is streamed + :var int channels: Number of audio channels used by :class:`Listener` + :var int chunk_size: Frame count inside the audio buffer + :var float interval: Clap interval in seconds + + :var method: The algorithm used for the detection of claps + :vartype method: class: `Munch` + :var actions: Collection of defined actions + :vartype actions: list(str) """ - def __init__(self, controller=None): + def __init__(self): """Constructor method""" - self.controller = controller # Updated docs - """If the :attr:`controller` parameter is ``None``, an object of :class:`piclap.Controller` is assigned""" self.exit = False """**default:** ``False`` @@ -208,7 +202,7 @@

Source code for piclap._settings

         self.interval = 0.5
         """**default:** ``0.5``
 
-        Time duration to wait inside :meth:`piclap.Listener.clapWait()`"""
+        Time duration to wait inside :meth:`Listener.clapWait()`"""
         self.method = Objectify.fromDict({
             'name': 'threshold',
             'value': 7000
@@ -220,17 +214,15 @@ 

Source code for piclap._settings

             'on') and m.endswith('Claps')]
         """When the class initialised, it collects all the actions defined inside this class as well as any classes where are derived with this class as base class
 
-        **Condition:** __The method name defined should start with 'on' and end with 'Claps' with the clap count inbetween them.__
+        **Condition:** *The method name defined should start with 'on' and end with 'Claps' with the clap count inbetween them.*
         """
 
 
[docs] def on2Claps(self): - """Action performed when 2 claps are detected. As default, it call the method :meth:`piclap.Controller.flashLight` on pin 13""" - self.pi.flashLight(pin=13) + """Action performed when 2 claps are detected. As default, it call the method :meth:`Controller.flashLight` on pin 13""" print("Flashed light")
[docs] def on3Claps(self): - """Action performed when 3 claps are detected. As default, it call the method :meth:`piclap.Controller.toggleLight` on pin 24""" - self.pi.toggleLight(pin=24) + """Action performed when 3 claps are detected. As default, it call the method :meth:`Controller.toggleLight` on pin 24""" print("Toggled light")
[docs] def on4Claps(self): diff --git a/docs/_sources/getting-started.rst.txt b/docs/_sources/getting-started.rst.txt index c58bf20..c8127eb 100644 --- a/docs/_sources/getting-started.rst.txt +++ b/docs/_sources/getting-started.rst.txt @@ -72,30 +72,22 @@ Using Pip package Example code ------------ -.. code-block:: +Writing an app using Pi Clap is only 3 lines it need ideally. - from piclap import Listener, Settings +.. literalinclude:: ../../example/app.py + :language: python + :linenos: +But this is not the real world senario. You will need more control over the settings that match your microphone and operating system. Following code give your more flexibility. - class Config(Settings): - '''This is an user defined derived class with `piclap.Settings` as base class''' +.. literalinclude:: ../../example/advanced.app.py + :language: python + :emphasize-lines: 6-23,26-28,32-33 + :linenos: - def __init__(self): - '''Defines new and override existing properties here''' - self.chunk_size = 512 # Reduce as power of 2 if pyaudio overflow - self.interval = 0.5 # Adjust interval between claps - self.method.value = 300 # Threshold value adjustment +If you are using **Raspberry Pi**, use following code: - def on2Claps(self): - '''Custom action for 2 claps''' - print("Light flashed on pin", 4) - - def on3Claps(self): - '''Custom action for 3 claps''' - print("Light toggled on pin", 6) - - config = Config() - listener = Listener(config) - listener.start() - -If you are using **Raspberry Pi**, use the extended version of this example: `app.py `_ +.. literalinclude:: ../../example/rpi.app.py + :language: python + :emphasize-lines: 4,7-20,30,37-38,43,45-47 + :linenos: diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js index fc073e0..078dc43 100644 --- a/docs/_static/documentation_options.js +++ b/docs/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '1.3', + VERSION: '1.3.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/genindex.html b/docs/genindex.html index fd88b4a..1251fd4 100644 --- a/docs/genindex.html +++ b/docs/genindex.html @@ -7,7 +7,7 @@ - Index — Pi Clap 1.3 documentation + Index — Pi Clap 1.3.1 documentation @@ -199,16 +199,14 @@

C

  • channels (piclap.Settings attribute)
  • chunk_size (piclap.Settings attribute) -
  • -
  • claps (piclap.Listener attribute)
  • diff --git a/docs/getting-started.html b/docs/getting-started.html index e15be00..04c253e 100644 --- a/docs/getting-started.html +++ b/docs/getting-started.html @@ -7,7 +7,7 @@ - Getting Started — Pi Clap 1.3 documentation + Getting Started — Pi Clap 1.3.1 documentation @@ -244,32 +244,204 @@

    Using Pip package

    Example code

    -
    from piclap import Listener, Settings
    +

    Writing an app using Pi Clap is only 3 lines it need ideally.

    +
    1
    +2
    +3
    +4
    +5
    +6
    #!/usr/bin/python3
     
    +from piclap import *
    +
    +listener = Listener()
    +listener.start()
    +
    +
    +

    But this is not the real world senario. You will need more control over the settings that match your microphone and operating system. Following code give your more flexibility.

    +
     1
    + 2
    + 3
    + 4
    + 5
    + 6
    + 7
    + 8
    + 9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    #!/usr/bin/python3
    +
    +from piclap import *
    +
    +
    +class Config(Settings):
    +    '''Describes custom configurations and action methods to be executed based
    +    on the number of claps detected.
    +    '''
    +
    +    def __init__(self):
    +        super().__init__()
    +        self.chunk_size = 512       # Reduce as power of 2 if pyaudio overflow
    +        self.interval = 0.5         # Adjust interval between claps
    +        self.method.value = 10000   # Threshold value adjustment
    +
    +    def on2Claps(self):
    +        '''Custom action for 2 claps'''
    +        print("Light flashed on pin 4")
    +
    +    def on3Claps(self):
    +        '''Custom action for 3 claps'''
    +        print("Light toggled on pin 6")
    +
    +
    +def main():
    +    config = Config()
    +    listener = Listener(config)
    +    listener.start()
    +
    +
    +if __name__ == '__main__':
    +    main()
    +
    +
    +

    If you are using Raspberry Pi, use following code:

    +
     1
    + 2
    + 3
    + 4
    + 5
    + 6
    + 7
    + 8
    + 9
    +10
    +11
    +12
    +13
    +14
    +15
    +16
    +17
    +18
    +19
    +20
    +21
    +22
    +23
    +24
    +25
    +26
    +27
    +28
    +29
    +30
    +31
    +32
    +33
    +34
    +35
    +36
    +37
    +38
    +39
    +40
    +41
    +42
    +43
    +44
    +45
    +46
    +47
    +48
    +49
    +50
    +51
    +52
    +53
    +54
    +55
    +56
    +57
    #!/usr/bin/python3
    +
    +from piclap import *
    +from gpiozero import LED
    +
    +
    +class PiController:
    +    '''Describes the controller methods which are usually used while connected
    +    to a raspberry pi controller using the module `gpiozero`.
    +    '''
    +
    +    def toggleLight(self, pin=24):
    +        led = LED(pin)
    +        led.toggle()
    +        print("Light toggled on pin", pin)
    +
    +    def lightBlinker(self, pin, times=10):
    +        led = LED(pin)
    +        led.blink(n=times)
    +        print("Light blinks", times, "times on pin", pin)
    +
     
     class Config(Settings):
    -    '''This is an user defined derived class with `piclap.Settings` as base class'''
    +    '''Describes custom configurations and action methods to be executed based
    +    on the number of claps detected.
    +    '''
     
         def __init__(self):
    -        '''Defines new and override existing properties here'''
    -        self.chunk_size = 512       # Reduce as power of 2 if pyaudio overflow
    +        super().__init__()
    +        self.controller = PiController()
    +        self.chunk_size = 512       # Reduce as power of 2 if pyaudio overflow
             self.interval = 0.5         # Adjust interval between claps
    -        self.method.value = 300             # Threshold value adjustment
    +        self.method.value = 10000   # Threshold value adjustment
     
         def on2Claps(self):
             '''Custom action for 2 claps'''
    -        print("Light flashed on pin", 4)
    +        led = LED(4)
    +        led.blink()
    +        print("Light flashed on pin 4")
     
         def on3Claps(self):
    -        '''Custom action for 3 claps'''
    -        print("Light toggled on pin", 6)
    -
    -config = Config()
    -listener = Listener(config)
    -listener.start()
    +        '''Custom action from PiController for 3 claps'''
    +        self.controller.toggleLight(pin=6)
    +
    +    def on5Claps(self):
    +        '''Custom action from PiController for 5 claps'''
    +        self.controller.lightBlinker(pin=5, times=5)
    +
    +
    +def main():
    +    config = Config()
    +    listener = Listener(config)
    +    listener.start()
    +
    +
    +if __name__ == '__main__':
    +    main()
     
    - -

    If you are using Raspberry Pi, use the extended version of this example: app.py

    +
    diff --git a/docs/index.html b/docs/index.html index a3851e7..2409658 100644 --- a/docs/index.html +++ b/docs/index.html @@ -7,7 +7,7 @@ - Welcome to Pi Clap — Pi Clap 1.3 documentation + Welcome to Pi Clap — Pi Clap 1.3.1 documentation diff --git a/docs/license.html b/docs/license.html index f7f52c6..28e3de4 100644 --- a/docs/license.html +++ b/docs/license.html @@ -7,7 +7,7 @@ - <no title> — Pi Clap 1.3 documentation + <no title> — Pi Clap 1.3.1 documentation diff --git a/docs/objects.inv b/docs/objects.inv index 4cbcfb6..5e73ad9 100644 Binary files a/docs/objects.inv and b/docs/objects.inv differ diff --git a/docs/piclap.html b/docs/piclap.html index 3f3c402..9a4e9c8 100644 --- a/docs/piclap.html +++ b/docs/piclap.html @@ -7,7 +7,7 @@ - Documentation — Pi Clap 1.3 documentation + Documentation — Pi Clap 1.3.1 documentation @@ -270,22 +270,18 @@

    Listener Module

    -class piclap.Settings(controller=None)[source]
    -

    This class describes all the configurations needed for the piclap.Listener to work.

    +class piclap.Settings[source] +

    This class describes all the configurations needed for the Listener to work.

    -
    Parameters
    -

    controller (class: piclap.Controller) – A piclap.Controller object, defaults to None

    -
    -
    Variables
    -
      -
    • controller (class: piclap.Controller) – Holds the controller object passed as argument

    • -
    • exit (boolean) – Holds the controller object passed as argument

    • -
    • rate (int) – Holds the controller object passed as argument

    • -
    • channels (int) – Holds the controller object passed as argument

    • -
    • chunk_size (int) – Holds the controller object passed as argument

    • -
    • interval (float) – Holds the controller object passed as argument

    • -
    • method (class: piclap.Controller) – Holds the controller object passed as argument

    • -
    • actions (class: piclap.Controller) – Holds the controller object passed as argument

    • +
      Variables
      +
        +
      • exit (boolean) – Exit flag the determine the exit state of Listener

      • +
      • rate (int) – Bitrate at which input audio is streamed

      • +
      • channels (int) – Number of audio channels used by Listener

      • +
      • chunk_size (int) – Frame count inside the audio buffer

      • +
      • interval (float) – Clap interval in seconds

      • +
      • method (class: Munch) – The algorithm used for the detection of claps

      • +
      • actions (list(str)) – Collection of defined actions

    @@ -293,7 +289,7 @@

    Settings Module actions

    When the class initialised, it collects all the actions defined inside this class as well as any classes where are derived with this class as base class

    -

    Condition: __The method name defined should start with ‘on’ and end with ‘Claps’ with the clap count inbetween them.__

    +

    Condition: The method name defined should start with ‘on’ and end with ‘Claps’ with the clap count inbetween them.

    @@ -310,12 +306,6 @@

    Settings Module -
    -controller
    -

    If the controller parameter is None, an object of piclap.Controller is assigned

    -

    -
    exit
    @@ -327,7 +317,7 @@

    Settings Module interval

    default: 0.5

    -

    Time duration to wait inside piclap.Listener.clapWait()

    +

    Time duration to wait inside Listener.clapWait()

    @@ -340,13 +330,13 @@

    Settings Module
    on2Claps()[source]
    -

    Action performed when 2 claps are detected. As default, it call the method piclap.Controller.flashLight() on pin 13

    +

    Action performed when 2 claps are detected. As default, it call the method Controller.flashLight() on pin 13

    on3Claps()[source]
    -

    Action performed when 3 claps are detected. As default, it call the method piclap.Controller.toggleLight() on pin 24

    +

    Action performed when 3 claps are detected. As default, it call the method Controller.toggleLight() on pin 24

    diff --git a/docs/search.html b/docs/search.html index 20d4bd9..b93f51f 100644 --- a/docs/search.html +++ b/docs/search.html @@ -7,7 +7,7 @@ - Search — Pi Clap 1.3 documentation + Search — Pi Clap 1.3.1 documentation diff --git a/docs/searchindex.js b/docs/searchindex.js index 2e8ef6b..8ee99d5 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["genindex","getting-started","index","license","piclap"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["genindex.rst","getting-started.rst","index.rst","license.rst","piclap.rst"],objects:{"piclap.Listener":{clapWait:[4,1,1,""],claps:[4,2,1,""],config:[4,2,1,""],input:[4,2,1,""],listenClaps:[4,1,1,""],processor:[4,2,1,""],start:[4,1,1,""],stop:[4,1,1,""],stream:[4,2,1,""]},"piclap.Settings":{actions:[4,2,1,""],channels:[4,2,1,""],chunk_size:[4,2,1,""],controller:[4,2,1,""],exit:[4,2,1,""],interval:[4,2,1,""],method:[4,2,1,""],on2Claps:[4,1,1,""],on3Claps:[4,1,1,""],on4Claps:[4,1,1,""],rate:[4,2,1,""],updateMethod:[4,1,1,""]},"piclap.SignalProcessor":{alg_id:[4,2,1,""],algorithm:[4,2,1,""],findClap:[4,1,1,""],useFFT:[4,1,1,""],useFiter:[4,1,1,""],useThreshold:[4,1,1,""],useWavelets:[4,1,1,""]},piclap:{Listener:[4,0,1,""],Settings:[4,0,1,""],SignalProcessor:[4,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"1024":4,"2020":[2,3],"300":1,"44100":4,"512":1,"55876":2,"7000":4,"boolean":4,"class":[1,4],"default":4,"float":4,"import":1,"int":4,"new":[1,4],"return":4,"true":4,AND:[2,3],Adding:2,BUT:[2,3],FOR:[2,3],NOT:[2,3],THE:[2,3],The:[2,3,4],USE:[2,3],Use:1,Using:2,WITH:[2,3],__init__:1,__the:4,abov:[2,3],action:[1,2,3,4],adafruit:2,add:2,adjust:1,advanc:2,after:2,alexa:2,alg_id:4,algorithm:[2,4],all:[2,3,4],amazon:2,analog:2,ani:[2,3,4],app:1,apt:1,argument:4,aris:[2,3],arrai:4,articl:2,assign:4,associ:[2,3],audio:[2,4],author:[2,3],autom:2,automat:2,base:[1,4],below:1,between:1,binari:4,board:2,bool:4,bread:2,brew:1,buffer:4,build_ext:1,byte_stream:4,bytearrai:4,call:4,card:2,cento:2,channel:4,charg:[2,3],child:4,chunk:4,chunk_siz:[1,4],claim:[2,3],clap:[1,4],clapwait:4,clone:2,close:4,code:2,collect:4,com:[1,2],comput:2,condit:[2,3,4],config:[1,4],configur:[2,4],connect:[2,3,4],contain:4,contract:[2,3],control:4,copi:[2,3],copyright:[2,3],count:4,current:4,custom:1,damag:[2,3],data:4,deal:[2,3],debian:2,def:1,defin:[1,4],deriv:[1,4],describ:4,detail:4,detect:[2,4],detection_algorithm:4,dev:1,devel:1,devic:2,dict:4,distribut:[2,3],dnf:1,document:[2,3],download:1,driver:2,durat:4,end:4,epel:1,equal:4,etc:2,event:[2,3],exampl:2,execut:4,exist:1,exit:4,express:[2,3],extend:1,fals:4,fedora:2,fedoraproject:1,file:[2,3],findclap:4,finish:4,fit:[2,3],flag:4,flash:1,flashlight:4,follow:[2,3],found:4,frame:4,free:[2,3],from:[1,2,3,4],furnish:[2,3],get:2,git:2,github:1,given:[1,4],global:1,googl:2,gpiozero:2,grant:[2,3],greater:4,here:1,herebi:[2,3],hold:4,holder:[2,3],home:2,http:[1,2],identif:4,ifttt:2,imag:2,implement:4,impli:[2,3],inbetween:4,includ:[1,2,3],infring:[2,3],initi:4,initialis:4,input:4,insid:4,instal:2,instruct:2,integ:4,interv:[1,4],jack:2,john:[2,3],keyboard:4,keyboardinterrupt:4,kind:[2,3],latest:1,learn:2,liabil:[2,3],liabl:[2,3],lib:1,licens:3,light:1,like:2,limit:[2,3],linux:2,listen:[1,2],listenclap:4,load:2,local:1,lock:4,mac:2,maco:2,make:1,manual:2,maximum:4,merchant:[2,3],merg:[2,3],method:[1,4],microphon:[2,4],mit:[2,3],modifi:[2,3],modul:[1,2],mono:4,more:4,munch:[1,2,4],name:4,need:[2,4],nikhil:[2,3],nikhiljohn10:1,noarch:1,non:[2,3],none:4,notic:[2,3],number:4,object:4,obtain:[2,3],on2clap:[1,4],on3clap:[1,4],on4clap:4,open:4,option:[1,2],org:[1,2],other:[2,3],otherwis:[2,3,4],out:[2,3],overflow:1,overrid:1,packag:2,paramet:4,particular:[2,3],pass:4,perform:4,permiss:[2,3],permit:[2,3],person:[2,3],piclap:[1,4],pin:[1,4],pip3:1,pip:2,portaudio19:1,portaudio:[1,2],portion:[2,3],power:1,press:4,print:1,process:4,processor:4,properti:[1,4],provid:[2,3],pub:1,publish:[2,3],purpos:[2,3],pyaudio:[1,2,4],python37:1,python3:1,python:2,rais:4,rasbian:2,raspberri:[1,2],raspberrypi:2,raspberrytip:2,rate:4,read:4,receiv:4,recurs:4,redhat:1,reduc:1,refresh:1,releas:1,reset:4,restart:2,restrict:[2,3],right:[2,3],rpm:1,run:[1,4],safe:4,sampl:4,search:4,second:4,select:4,selector:4,self:1,sell:[2,3],set:[1,2],shall:[2,3],should:4,signal:4,signalprocessor:2,softwar:[2,3],sourc:4,sreach:4,start:[2,4],stop:4,store:4,str:4,stream:4,subject:[2,3],sublicens:[2,3],substanti:[2,3],sudo:1,termin:4,than:4,them:4,thi:[1,2,3,4],thread:4,threadnam:4,threshold:[1,4],throughout:4,time:4,toggl:1,togglelight:4,tort:[2,3],tutsplu:2,type:4,ubuntu:2,udo:1,until:4,updat:[1,4],updatemethod:4,upgrad:1,usb:2,use:[1,2,3],used:4,usefft:4,usefit:4,user:[1,4],uses:4,usethreshold:4,usewavelet:4,using:[1,2,4],usr:1,uvh:1,valu:[1,4],variabl:4,version:1,wait:4,warranti:[2,3],well:4,when:4,where:4,whether:[2,3],which:4,whom:[2,3],without:[2,3],work:4,www:2,x86_64:1,yet:4,you:1,yum:1},titles:["Index","Getting Started","Welcome to Pi Clap","<no title>","Documentation"],titleterms:{Using:1,cento:1,clap:2,clone:1,code:1,content:2,debian:1,depend:[1,2],document:4,exampl:1,featur:2,fedora:1,get:1,git:1,hardwar:2,index:0,instal:1,licens:2,listen:4,maco:1,modul:4,packag:1,pip:1,platform:2,rasbian:1,refer:2,requir:2,set:4,signalprocessor:4,start:1,support:2,ubuntu:1,upcom:2,welcom:2}}) \ No newline at end of file +Search.setIndex({docnames:["genindex","getting-started","index","license","piclap"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["genindex.rst","getting-started.rst","index.rst","license.rst","piclap.rst"],objects:{"piclap.Listener":{clapWait:[4,1,1,""],claps:[4,2,1,""],config:[4,2,1,""],input:[4,2,1,""],listenClaps:[4,1,1,""],processor:[4,2,1,""],start:[4,1,1,""],stop:[4,1,1,""],stream:[4,2,1,""]},"piclap.Settings":{actions:[4,2,1,""],channels:[4,2,1,""],chunk_size:[4,2,1,""],exit:[4,2,1,""],interval:[4,2,1,""],method:[4,2,1,""],on2Claps:[4,1,1,""],on3Claps:[4,1,1,""],on4Claps:[4,1,1,""],rate:[4,2,1,""],updateMethod:[4,1,1,""]},"piclap.SignalProcessor":{alg_id:[4,2,1,""],algorithm:[4,2,1,""],findClap:[4,1,1,""],useFFT:[4,1,1,""],useFiter:[4,1,1,""],useThreshold:[4,1,1,""],useWavelets:[4,1,1,""]},piclap:{Listener:[4,0,1,""],Settings:[4,0,1,""],SignalProcessor:[4,0,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute"},terms:{"10000":1,"1024":4,"2020":[2,3],"44100":4,"512":1,"55876":2,"7000":4,"boolean":4,"class":[1,4],"default":4,"float":4,"import":1,"int":4,"new":4,"return":4,"super":1,"true":4,"while":1,AND:[2,3],Adding:2,BUT:[2,3],But:1,FOR:[2,3],NOT:[2,3],THE:[2,3],The:[2,3,4],USE:[2,3],Use:1,Using:2,WITH:[2,3],__init__:1,__main__:1,__name__:1,abov:[2,3],action:[1,2,3,4],adafruit:2,add:2,adjust:1,advanc:2,after:2,alexa:2,alg_id:4,algorithm:[2,4],all:[2,3,4],amazon:2,analog:2,ani:[2,3,4],app:1,apt:1,aris:[2,3],arrai:4,articl:2,assign:4,associ:[2,3],audio:[2,4],author:[2,3],autom:2,automat:2,base:[1,4],below:1,between:1,bin:1,binari:4,bitrat:4,blink:1,board:2,bool:4,bread:2,brew:1,buffer:4,build_ext:1,byte_stream:4,bytearrai:4,call:4,card:2,cento:2,channel:4,charg:[2,3],child:4,chunk:4,chunk_siz:[1,4],claim:[2,3],clap:[1,4],clapwait:4,clone:2,close:4,code:2,collect:4,com:[1,2],comput:2,condit:[2,3,4],config:[1,4],configur:[1,2,4],connect:[1,2,3,4],contain:4,contract:[2,3],control:[1,4],copi:[2,3],copyright:[2,3],count:4,current:4,custom:1,damag:[2,3],data:4,deal:[2,3],debian:2,def:1,defin:4,deriv:4,describ:[1,4],detail:4,detect:[1,2,4],detection_algorithm:4,determin:4,dev:1,devel:1,devic:2,dict:4,distribut:[2,3],dnf:1,document:[2,3],download:1,driver:2,durat:4,end:4,epel:1,equal:4,etc:2,event:[2,3],exampl:2,execut:[1,4],exit:4,express:[2,3],fals:4,fedora:2,fedoraproject:1,file:[2,3],findclap:4,finish:4,fit:[2,3],flag:4,flash:1,flashlight:4,flexibl:1,follow:[1,2,3],found:4,frame:4,free:[2,3],from:[1,2,3,4],furnish:[2,3],get:2,git:2,github:1,give:1,given:[1,4],global:1,googl:2,gpiozero:[1,2],grant:[2,3],greater:4,herebi:[2,3],holder:[2,3],home:2,http:[1,2],ideal:1,identif:4,ifttt:2,imag:2,implement:4,impli:[2,3],inbetween:4,includ:[1,2,3],infring:[2,3],initi:4,initialis:4,input:4,insid:4,instal:2,instruct:2,integ:4,interv:[1,4],jack:2,john:[2,3],keyboard:4,keyboardinterrupt:4,kind:[2,3],latest:1,learn:2,led:1,liabil:[2,3],liabl:[2,3],lib:1,licens:3,light:1,lightblink:1,like:2,limit:[2,3],line:1,linux:2,list:4,listen:[1,2],listenclap:4,load:2,local:1,lock:4,mac:2,maco:2,main:1,make:1,manual:2,match:1,maximum:4,merchant:[2,3],merg:[2,3],method:[1,4],microphon:[1,2,4],mit:[2,3],modifi:[2,3],modul:[1,2],mono:4,more:[1,4],munch:[1,2,4],name:4,need:[1,2,4],nikhil:[2,3],nikhiljohn10:1,noarch:1,non:[2,3],none:4,notic:[2,3],number:[1,4],object:4,obtain:[2,3],on2clap:[1,4],on3clap:[1,4],on4clap:4,on5clap:1,onli:1,open:4,oper:1,option:[1,2],org:[1,2],other:[2,3],otherwis:[2,3,4],out:[2,3],over:1,overflow:1,packag:2,paramet:4,particular:[2,3],perform:4,permiss:[2,3],permit:[2,3],person:[2,3],piclap:[1,4],picontrol:1,pin:[1,4],pip3:1,pip:2,portaudio19:1,portaudio:[1,2],portion:[2,3],power:1,press:4,print:1,process:4,processor:4,properti:4,provid:[2,3],pub:1,publish:[2,3],purpos:[2,3],pyaudio:[1,2,4],python37:1,python3:1,python:2,rais:4,rasbian:2,raspberri:[1,2],raspberrypi:2,raspberrytip:2,rate:4,read:4,real:1,receiv:4,recurs:4,redhat:1,reduc:1,refresh:1,releas:1,reset:4,restart:2,restrict:[2,3],right:[2,3],rpm:1,run:[1,4],safe:4,sampl:4,search:4,second:4,select:4,selector:4,self:1,sell:[2,3],senario:1,set:[1,2],shall:[2,3],should:4,signal:4,signalprocessor:2,softwar:[2,3],sourc:4,sreach:4,start:[2,4],state:4,stop:4,store:4,str:4,stream:4,subject:[2,3],sublicens:[2,3],substanti:[2,3],sudo:1,system:1,termin:4,than:4,them:4,thi:[1,2,3,4],thread:4,threadnam:4,threshold:[1,4],throughout:4,time:[1,4],toggl:1,togglelight:[1,4],tort:[2,3],tutsplu:2,type:4,ubuntu:2,udo:1,until:4,updat:[1,4],updatemethod:4,upgrad:1,usb:2,use:[1,2,3],used:[1,4],usefft:4,usefit:4,user:4,uses:4,usethreshold:4,usewavelet:4,using:[1,2,4],usr:1,usual:1,uvh:1,valu:[1,4],variabl:4,wait:4,warranti:[2,3],well:4,when:4,where:4,whether:[2,3],which:[1,4],whom:[2,3],without:[2,3],work:4,world:1,write:1,www:2,x86_64:1,yet:4,you:1,your:1,yum:1},titles:["Index","Getting Started","Welcome to Pi Clap","<no title>","Documentation"],titleterms:{Using:1,cento:1,clap:2,clone:1,code:1,content:2,debian:1,depend:[1,2],document:4,exampl:1,featur:2,fedora:1,get:1,git:1,hardwar:2,index:0,instal:1,licens:2,listen:4,maco:1,modul:4,packag:1,pip:1,platform:2,rasbian:1,refer:2,requir:2,set:4,signalprocessor:4,start:1,support:2,ubuntu:1,upcom:2,welcom:2}}) \ No newline at end of file diff --git a/docs/source/getting-started.rst b/docs/source/getting-started.rst index c58bf20..c8127eb 100644 --- a/docs/source/getting-started.rst +++ b/docs/source/getting-started.rst @@ -72,30 +72,22 @@ Using Pip package Example code ------------ -.. code-block:: +Writing an app using Pi Clap is only 3 lines it need ideally. - from piclap import Listener, Settings +.. literalinclude:: ../../example/app.py + :language: python + :linenos: +But this is not the real world senario. You will need more control over the settings that match your microphone and operating system. Following code give your more flexibility. - class Config(Settings): - '''This is an user defined derived class with `piclap.Settings` as base class''' +.. literalinclude:: ../../example/advanced.app.py + :language: python + :emphasize-lines: 6-23,26-28,32-33 + :linenos: - def __init__(self): - '''Defines new and override existing properties here''' - self.chunk_size = 512 # Reduce as power of 2 if pyaudio overflow - self.interval = 0.5 # Adjust interval between claps - self.method.value = 300 # Threshold value adjustment +If you are using **Raspberry Pi**, use following code: - def on2Claps(self): - '''Custom action for 2 claps''' - print("Light flashed on pin", 4) - - def on3Claps(self): - '''Custom action for 3 claps''' - print("Light toggled on pin", 6) - - config = Config() - listener = Listener(config) - listener.start() - -If you are using **Raspberry Pi**, use the extended version of this example: `app.py `_ +.. literalinclude:: ../../example/rpi.app.py + :language: python + :emphasize-lines: 4,7-20,30,37-38,43,45-47 + :linenos: diff --git a/example/advanced.app.py b/example/advanced.app.py new file mode 100644 index 0000000..5651cca --- /dev/null +++ b/example/advanced.app.py @@ -0,0 +1,33 @@ +#!/usr/bin/python3 + +from piclap import * + + +class Config(Settings): + '''Describes custom configurations and action methods to be executed based + on the number of claps detected. + ''' + + def __init__(self): + super().__init__() + self.chunk_size = 512 # Reduce as power of 2 if pyaudio overflow + self.interval = 0.5 # Adjust interval between claps + self.method.value = 10000 # Threshold value adjustment + + def on2Claps(self): + '''Custom action for 2 claps''' + print("Light flashed on pin 4") + + def on3Claps(self): + '''Custom action for 3 claps''' + print("Light toggled on pin 6") + + +def main(): + config = Config() + listener = Listener(config) + listener.start() + + +if __name__ == '__main__': + main() diff --git a/example/app.py b/example/app.py index 0a62764..3796678 100644 --- a/example/app.py +++ b/example/app.py @@ -1,78 +1,6 @@ #!/usr/bin/python3 -''' - - ################### - ## ## - ## Pi-Clap ## - ## ## - ################### - -Repo: https://github.com/nikhiljohn10/pi-clap -Author: Nikhil John -License: MIT -''' - -try: - import piclap -except(ModuleNotFoundError): - import os - import sys - sys.path.append(os.path.abspath('.')) - -# Above code is only needed if piclap module is not installed using pip install - -# Uncomment line numbers 27, 35, 36, 40, 41, 58, 59 if you are using Raspberry Pi GPIO from piclap import * -# from gpiozero import LED - -class PiController: - '''Describes the controller methods which are usually used while connected - to a raspberry pi controller using the module `gpiozero`. This class is not - need when used without a Raspberry Pi. - ''' - def lightBlinker(self, pin, times=10): - # led = LED(pin) - # led.blink(n=times) - print("Light blinks", times, "times on pin", pin) - - def toggleLight(self, pin=24): - # led = LED(pin) - # led.toggle() - print("Light toggled on pin", pin) - -class Config(Settings): - '''Describes custom configurations and action methods to be executed based - on the number of claps detected. - ''' - - def __init__(self): - super().__init__() - self.controller = PiController() - self.chunk_size = 512 # Reduce as power of 2 if pyaudio overflow - self.interval = 0.5 # Adjust interval between claps - self.method.value = 10000 # Threshold value adjustment - - def on2Claps(self): - '''Custom action for 2 claps''' - # led = LED(4) - # led.blink() - print("Light flashed on pin 4") - - def on3Claps(self): - '''Custom action for 3 claps''' - self.controller.toggleLight(pin=6) - - def on5Claps(self): - '''Custom action for 5 claps''' - self.controller.lightBlinker(pin=5, times=5) - - -def main(): - config = Config() - listener = Listener(config) - listener.start() - -if __name__ == '__main__': - main() +listener = Listener() +listener.start() diff --git a/example/rpi.app.py b/example/rpi.app.py new file mode 100644 index 0000000..cc478c1 --- /dev/null +++ b/example/rpi.app.py @@ -0,0 +1,57 @@ +#!/usr/bin/python3 + +from piclap import * +from gpiozero import LED + + +class PiController: + '''Describes the controller methods which are usually used while connected + to a raspberry pi controller using the module `gpiozero`. + ''' + + def toggleLight(self, pin=24): + led = LED(pin) + led.toggle() + print("Light toggled on pin", pin) + + def lightBlinker(self, pin, times=10): + led = LED(pin) + led.blink(n=times) + print("Light blinks", times, "times on pin", pin) + + +class Config(Settings): + '''Describes custom configurations and action methods to be executed based + on the number of claps detected. + ''' + + def __init__(self): + super().__init__() + self.controller = PiController() + self.chunk_size = 512 # Reduce as power of 2 if pyaudio overflow + self.interval = 0.5 # Adjust interval between claps + self.method.value = 10000 # Threshold value adjustment + + def on2Claps(self): + '''Custom action for 2 claps''' + led = LED(4) + led.blink() + print("Light flashed on pin 4") + + def on3Claps(self): + '''Custom action from PiController for 3 claps''' + self.controller.toggleLight(pin=6) + + def on5Claps(self): + '''Custom action from PiController for 5 claps''' + self.controller.lightBlinker(pin=5, times=5) + + +def main(): + config = Config() + listener = Listener(config) + listener.start() + + +if __name__ == '__main__': + main() diff --git a/piclap/__init__.py b/piclap/__init__.py index 29ec650..1e6cb2e 100644 --- a/piclap/__init__.py +++ b/piclap/__init__.py @@ -12,6 +12,6 @@ from ._processor import SignalProcessor __project__ = 'pi-clap' -__version__ = '1.3' +__version__ = '1.3.1' __author__ = 'Nikhil John' __all__ = ['Settings', 'Listener', 'SignalProcessor'] diff --git a/piclap/_settings.py b/piclap/_settings.py index 17a41d5..8716646 100644 --- a/piclap/_settings.py +++ b/piclap/_settings.py @@ -2,28 +2,22 @@ class Settings: - """This class describes all the configurations needed for the :class:`piclap.Listener` to work. - - :param controller: A :class:`piclap.Controller` object, defaults to None - :type controller: class: `piclap.Controller` - :var controller: Holds the controller object passed as argument - :vartype controller: class: `piclap.Controller` - :var boolean exit: Holds the controller object passed as argument - :var int rate: Holds the controller object passed as argument - :var int channels: Holds the controller object passed as argument - :var int chunk_size: Holds the controller object passed as argument - :var float interval: Holds the controller object passed as argument - - :var method: Holds the controller object passed as argument - :vartype method: class: `piclap.Controller` - :var actions: Holds the controller object passed as argument - :vartype actions: class: `piclap.Controller` + """This class describes all the configurations needed for the :class:`Listener` to work. + + :var boolean exit: Exit flag the determine the exit state of :class:`Listener` + :var int rate: Bitrate at which input audio is streamed + :var int channels: Number of audio channels used by :class:`Listener` + :var int chunk_size: Frame count inside the audio buffer + :var float interval: Clap interval in seconds + + :var method: The algorithm used for the detection of claps + :vartype method: class: `Munch` + :var actions: Collection of defined actions + :vartype actions: list(str) """ - def __init__(self, controller=None): + def __init__(self): """Constructor method""" - self.controller = controller # Updated docs - """If the :attr:`controller` parameter is ``None``, an object of :class:`piclap.Controller` is assigned""" self.exit = False """**default:** ``False`` @@ -44,7 +38,7 @@ def __init__(self, controller=None): self.interval = 0.5 """**default:** ``0.5`` - Time duration to wait inside :meth:`piclap.Listener.clapWait()`""" + Time duration to wait inside :meth:`Listener.clapWait()`""" self.method = Objectify.fromDict({ 'name': 'threshold', 'value': 7000 @@ -56,17 +50,15 @@ def __init__(self, controller=None): 'on') and m.endswith('Claps')] """When the class initialised, it collects all the actions defined inside this class as well as any classes where are derived with this class as base class - **Condition:** __The method name defined should start with 'on' and end with 'Claps' with the clap count inbetween them.__ + **Condition:** *The method name defined should start with 'on' and end with 'Claps' with the clap count inbetween them.* """ def on2Claps(self): - """Action performed when 2 claps are detected. As default, it call the method :meth:`piclap.Controller.flashLight` on pin 13""" - self.pi.flashLight(pin=13) + """Action performed when 2 claps are detected. As default, it call the method :meth:`Controller.flashLight` on pin 13""" print("Flashed light") def on3Claps(self): - """Action performed when 3 claps are detected. As default, it call the method :meth:`piclap.Controller.toggleLight` on pin 24""" - self.pi.toggleLight(pin=24) + """Action performed when 3 claps are detected. As default, it call the method :meth:`Controller.toggleLight` on pin 24""" print("Toggled light") def on4Claps(self): diff --git a/tests/test_processor.py b/tests/test_processor.py new file mode 100644 index 0000000..01c3524 --- /dev/null +++ b/tests/test_processor.py @@ -0,0 +1,29 @@ +import os +import sys +from array import array +sys.path.append(os.path.abspath('.')) + +from piclap import SignalProcessor +from munch import DefaultMunch as Objectify + +DETECTION_ALGORITHMS = [ + 'threshold', + 'filter', + 'fft', + 'wavelet' +] + +def test_threshold(): + proc = SignalProcessor(method=Objectify.fromDict({ + 'name': 'threshold', + 'value': 100 + }, False)) + assert proc.algorithm.name == DETECTION_ALGORITHMS[proc.alg_id], 'Algorithm does not match' + assert proc.findClap(data=array('b', [99])) == False, 'Clap Detection Error' + assert proc.findClap(data=array('b', [100])) == False, 'Clap Detection Error' + assert proc.findClap(data=array('b', [101])) == True, 'Clap Detection Error' + assert proc.findClap(data=array('b', [102])) == True, 'Clap Detection Error' + + +if __name__ == '__main__': + test_threshold() diff --git a/tests/test_settings.py b/tests/test_settings.py index bf568cd..075ab09 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -11,7 +11,7 @@ def getSettings(): config.customPin = 13 return config -def test(): +def test_updating(): old_config = Settings() new_config = getSettings() assert new_config.chunk_size != old_config.chunk_size, 'Chunk Size not changed' @@ -19,4 +19,4 @@ def test(): assert new_config.customPin != None, 'Custom Pin not set' if __name__ == '__main__': - test() + test_updating()