float ofOpenALSoundPlayer::calculateAverage(float lowFreq, float hiFreq) { int lowBound = freqToIndex(lowFreq); int hiBound = freqToIndex(hiFreq); float avg = 0; for (int i = lowBound; i <= hiBound; i++) { avg += bins[i]; } avg /= (hiBound - lowBound + 1); return avg; }
vector<float> ivi_FFT::getLogAverages() { vector<float> samples = fftChannelL.getFftNormData(); vector<float> averages; int sampleRate = soundStream.getSampleRate(); for (int i = 1; i < 12; i++) { float avg = 0; int lowFreq; if ( i == 0 ) lowFreq = 0; else lowFreq = (int)((sampleRate/2) / (float) pow(2.0f, 12 - i)); int hiFreq = (int)((sampleRate/2) / (float) pow(2.0f, 11 - i)); int lowBound = freqToIndex(lowFreq); int hiBound = freqToIndex(hiFreq); for (int j = lowBound; j <= hiBound-0.5*(hiBound-lowBound); j++) { avg += samples[j]; } avg /= (hiBound - 0.5*(hiBound-lowBound) - lowBound +1); averages.push_back(avg); avg = 0; for (int j = lowBound+0.5*(hiBound-lowBound); j <= hiBound; j++) { avg += samples[j]; } avg /= (hiBound - 0.5*(hiBound-lowBound) - lowBound +1); // line has been changed since discussion in the comments // avg /= (hiBound - lowBound); averages.push_back(avg); } /* cout << "AVERAGES: "; for(int i=0; i < averages.size(); i++) { cout << averages[i] << " "; } cout << endl; */ return averages; }
int SpectrumAccumulator::work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { static size_t averageCounter = 1000000; static size_t delayCountdown = 10; double freqRange = m_maxFreq - m_minFreq; const float *in = reinterpret_cast<const float*>(input_items[0]); std::vector<gr::tag_t> tags; // get the tags in the current window get_tags_in_window(tags, 0, 0, 1); for(gr::tag_t &tag : tags) { if(pmt::write_string(tag.key) == "center_freq") { m_curFreq = pmt::to_double(tag.value); } } if(m_curFreq < m_minFreq || m_curFreq > m_maxFreq) { // current frequency is out of range -> request change to minimum frequency message_port_pub(m_newCenterFreqPort, pmt::from_double((m_minFreq + m_maxFreq)/2)); return noutput_items; } // when averaging is done for this frequency, hop to the next if(averageCounter >= m_nAvg) { averageCounter = 0; delayCountdown = 0.001 /* seconds */ * m_sampleRate/m_nfft; // countdown to allow settling double nextFreq = m_curFreq + m_sampleRate/5; // wrap around and reset if(nextFreq > m_maxFreq) { nextFreq = m_minFreq; for(size_t i = 0; i < m_avgVector.size(); i++) { m_avgVector[i].value *= 0.9; m_avgVector[i].count = m_avgVector[i].count * 0.9; } //resetAccumulation(); } message_port_pub(m_newCenterFreqPort, pmt::from_double(nextFreq)); } if(freqRange > m_sampleRate) { if(delayCountdown == 0) { int startIdx = freqToIndex(m_curFreq - m_sampleRate/2); gr::thread::scoped_lock lock(m_mutex); for(int i = 0; (i < m_nfft) && (startIdx+i < static_cast<int>(m_avgVector.size())); i++) { if(i >= m_nfft/2-2 && i <= m_nfft/2+1) { // skip the DC continue; } else if(startIdx + i >= 0) { m_avgVector[startIdx + i].value += in[i]; m_avgVector[startIdx + i].count++; } } averageCounter++; } } else { // display width is smaller than a single window AverageVector::size_type startIdx = -freqToIndex(m_curFreq - m_sampleRate/2); if(averageCounter == m_nAvg) { gr::thread::scoped_lock lock(m_mutex); for(size_t i = 0; (i < m_nfft); i++) { m_avgVector[i].value /= m_avgVector[i].count; m_avgVector[i].count = 1; } } else { gr::thread::scoped_lock lock(m_mutex); for(size_t i = 0; (i < m_nfft); i++) { m_avgVector[i].value += in[startIdx + i]; m_avgVector[i].count++; } } averageCounter++; } if(delayCountdown > 0) { delayCountdown--; } return noutput_items; }