|
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. |
[Prev in Thread] | Current Thread | [Next in Thread] |