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 = gr.wavfile_source("./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.
_______________________________________________
Discuss-gnuradio mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to