discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss-gnuradio] block that does simple tone detection


From: Affan Syed
Subject: [Discuss-gnuradio] block that does simple tone detection
Date: Fri, 26 Feb 2010 14:26:53 -0800

Hi all,
I have been building a simple block that can detect energy at a particular frequency, i.e. a tone detection block. The signal processing seemed simple enough for me, so I directly coded it. Essentially my tone_sink  takes in float point samples of the input signal (passed through a narrow bandpass filter), squares them and keeps a short term and long term average (I use an EWMA with different alpha's). I then generate a message if the short term avg is becomes much greater than the long term average. here is the .cc code

int 
tone_sink::work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
float *in = (float *) input_items[0];
    int count=0;
float sample_sqr;



 while (count < noutput_items){

 

//update both averages and observe the behavior over a period of time. 

 

sample_sqr=in[count]*in[count];//need to square to get energy of signal 

 

d_short_term_avg=d_alpha_short*sample_sqr+(1.0f - d_alpha_short)*d_short_term_avg;

 

d_long_term_avg=d_alpha_long*sample_sqr+(1.0f - d_alpha_long)*d_long_term_avg;

 

if ( (d_short_term_avg-d_long_term_avg) > THRESHOLD){

 

gr_message_sptr msg = gr_make_message(0, 0, 0, 1);//make a byte pkt to signal tone detection
d_target_queue->insert_tail(msg);       // send it
msg.reset();                // free it up

 

 

 }

 

 }

  // Tell runtime system how many input items we consumed on
  // each input stream.

  consume_each (noutput_items);

  // Tell runtime system how many output items we produced.
  return noutput_items;
}


However when I connect this sink on in a flow graph, my programs stalls. 

here is the python code 

class tone_graph(gr.top_block):

    def __init__(self):
        gr.top_block.__init__(self)
        audio_rate = AUDIO_RATE
        self.rcvd_pktq = gr.msg_queue()

         

        src = "" style="color: #c41a16">"./tone.wav", False)
         
        bp_coeff = gr.firdes.band_pass(1,audio_rate,TONE_FREQ-500,TONE_FREQ+500,100)
        bpf = gr.fir_filter_fff(1,bp_coeff)

        

        

        #speaker = audio.sink(audio_rate);

         

                

        sink = tone.sink(self.rcvd_pktq,0.5,0.95)
        #raw_wave = gr.wavfile_sink("raw.wav", 1, audio_rate,16)
        filt_wave = gr.wavfile_sink("filtered.wav", 1, audio_rate, 16)

        

        self.connect(src,bpf,filt_wave)
        #self.connect(src,raw_wave)
        #self.connect(src, speaker)
        self.connect(bpf,sink)# link the output of band pass filter to my tone rx module

        

        self.watcher = _queue_watcher_thread(self.rcvd_pktq, message_callback)

def main():

    fg = tone_graph()
    fg.start()

        

    try:
        print "Hit Ctrl-D to exit NOW."
        while True:
            raw_input("")
    except EOFError:
        print "\nExiting."
    #    #fg.wait()

# Main python entry


Further debugging this I observed that my CPU saturated while running the code on my sink block (I verified this using the activity monitor on my PowerBook G4, yes quite old PPC). So now the question is, am I doing something *that* intensive that a simple multiplication and EWMA update per sample is asking too much OR is there something wrong that I am doing ? Other seemingly as intensive functions from the GNU core work on my system so I am little surprised with this result.

Since the tone is at 18Khz I have lowered my AUDIO_RATE upto 40K but still now enough. 

Thanks for your help

Affan.  

reply via email to

[Prev in Thread] Current Thread [Next in Thread]