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;
}
Ejemplo n.º 2
0
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;
}