signal silence change detection

41 views
Skip to first unread message

enrike

unread,
Jan 17, 2015, 2:23:15 PM1/17/15
to pyo-d...@googlegroups.com
hi

Sorry if this question is too simple but I would like to analyse the
sound input and trigger a function when the amplitude rises above a
threshold. I need to detect changes between signal and silence.

I have done this in Supercollider with a DetectSilence which takes level
and falltime as arguments but I would like to see if there is an easy
way in Python to achieve the same.
http://doc.sccode.org/Classes/DetectSilence.html

I have been checking Follower but I dont understand very well how to use
it for my purposes

thanks

enrike

barmin

unread,
Jan 19, 2015, 4:48:44 AM1/19/15
to pyo-d...@googlegroups.com
Hi Enrike,

What you need is a Trigger (http://ajaxsoundstudio.com/pyodoc/api/classes/triggers.html).

Try something like:

[code]

def silence_detected():
print "Silence detected!"


src = Input(0)
env = Follower(src)
th = Thresh(env, .5, dir=1)
tf = TrigFunc(th, silence_detected)

s.gui(locals())

[/code]

Hope this helps,

Matthieu

enrike

unread,
Jan 19, 2015, 7:41:35 AM1/19/15
to pyo-d...@googlegroups.com
thanks!

barmin

unread,
Jan 20, 2015, 6:58:44 AM1/20/15
to pyo-d...@googlegroups.com
... although I'm not sure how to replicate the "time" argument in http://doc.sccode.org/Classes/DetectSilence.html.

Anyone knows how to trigger a function only if the triggering condition holds for longer than a given time?

Matthieu

Olivier Bélanger

unread,
Jan 30, 2015, 11:21:07 AM1/30/15
to pyo-discuss
Hi,

Here is a class that acts like SC's DetectSilence:

#!/usr/bin/env python
# encoding: utf-8
from pyo import *

s = Server().boot()

class DetectSilence:
    def __init__(self, input, thresh=0.001, time=0.1, callback=None):
        self.input = input
        self.thresh = thresh
        self.callback = callback
        # little bit tricky just to get the sampling rate!
        sr = input.getBaseObjects()[0].getServer().getSamplingRate()
        # waiting time in samples
        timeInSamps = int(time * sr)
        # envelope follower
        self.follow = Follower(self.input)
        # if follower is below threshold, self.gate holds 1, as audio
        # stream. Otherwise it holds 0
        self.gate = self.follow < self.thresh
        # send a trigger to reset the counter on both threshold crossing
        self.reset = Select(self.gate, value=[0,1]).mix(1)
        self.count = Count(self.reset)
        # if the count reach timeInSamps while the gate holds 1 (below
        # threshold), send a trigger to call self.detected method
        self.trig = Select(self.count, value=timeInSamps, mul=self.gate)
        self.func = TrigFunc(self.trig, self.detected)

    def detected(self):
        # if callback is defined, call it
        if self.callback != None:
            self.callback()
        # otherwise just print to the console
        else:
            print "Silence detected!"


# play the table once...
t = SndTable(SNDS_PATH+"/transparent.aif")
src = TableRead(t, t.getRate()).out()
#src = Input(0)

# callback on detected silence
def replay():
    src.out()

silence = DetectSilence(src, thresh=0.001, time=0.1, callback=replay)

s.gui(locals())


Olivier





Matthieu

--
You received this message because you are subscribed to the Google Groups "pyo-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyo-discuss+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

silence_detector.py

enrike

unread,
Jan 30, 2015, 11:23:21 AM1/30/15
to pyo-d...@googlegroups.com
thanks!


or., 2015.eko urtren 30a 17:20(e)an, Olivier Bélanger igorleak idatzi zuen:
> <mailto:bar...@bluewin.ch>>:
>
> ... although I'm not sure how to replicate the "time" argument in
> http://doc.sccode.org/Classes/__DetectSilence.html
> <http://doc.sccode.org/Classes/DetectSilence.html>.
>
> Anyone knows how to trigger a function only if the triggering
> condition holds for longer than a given time?
>
>
> Matthieu
>
> --
> You received this message because you are subscribed to the Google
> Groups "pyo-discuss" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to pyo-discuss+unsubscribe@__googlegroups.com
> <mailto:pyo-discuss%2Bunsu...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/__optout
> <https://groups.google.com/d/optout>.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "pyo-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to pyo-discuss...@googlegroups.com
> <mailto:pyo-discuss...@googlegroups.com>.

barmin

unread,
Jan 30, 2015, 11:31:49 AM1/30/15
to pyo-d...@googlegroups.com
Now I understand why I couldn't see how to do it ;-)

Thanks Olivier!

Olivier Bélanger

unread,
Jan 30, 2015, 12:12:56 PM1/30/15
to pyo-discuss
Yep, that was not an easy one! Maybe, it should be a single object...

Olivier


barmin

unread,
Jan 30, 2015, 12:36:22 PM1/30/15
to pyo-d...@googlegroups.com
You've made so many things so easy with pyo that I cannot help thinking this should be easier than that. I guess I'm a spolied brat ;-)

But wait... if I understand you solution correctly, it should be relatively easy to make a generic Trigger out of it. Something like

trig = Holds(cond=follow<thresh, time=0.1)

Any chance something like that would be included in a next version of pyo?

Matthieu

Le 30. 01. 15 18:12, Olivier Bélanger a écrit :
> Yep, that was not an easy one! Maybe, it should be a single object...
>
> Olivier
>
>
> 2015-01-30 11:31 GMT-05:00 barmin <bar...@bluewin.ch <mailto:bar...@bluewin.ch>>:
Reply all
Reply to author
Forward
0 new messages