Added Schumann resonances example.

master
Hannes Matuschek 11 years ago
parent 1ed605135a
commit 85e2ae3d74

@ -15,6 +15,10 @@ IF(SDR_WITH_PORTAUDIO)
add_executable(sdr_afsk1200 sdr_afsk1200.cc) add_executable(sdr_afsk1200 sdr_afsk1200.cc)
target_link_libraries(sdr_afsk1200 ${LIBS} libsdr) target_link_libraries(sdr_afsk1200 ${LIBS} libsdr)
qt5_wrap_cpp(sdr_schumann_MOC_SOURCES schumann.hh)
add_executable(sdr_schumann sdr_schumann.cc schumann.cc ${sdr_schumann_MOC_SOURCES})
target_link_libraries(sdr_schumann ${LIBS} libsdr libsdr-gui)
ENDIF(SDR_WITH_PORTAUDIO) ENDIF(SDR_WITH_PORTAUDIO)
IF(SDR_WITH_QT5 AND SDR_WITH_FFTW AND SDR_WITH_PORTAUDIO) IF(SDR_WITH_QT5 AND SDR_WITH_FFTW AND SDR_WITH_PORTAUDIO)

@ -0,0 +1,2 @@
#include "schumann.hh"

@ -0,0 +1,106 @@
#ifndef SCHUMANN_HH
#define SCHUMANN_HH
#include <libsdr/sdr.hh>
#include <libsdr/gui/gui.hh>
class Schumann: public sdr::gui::SpectrumProvider, public sdr::Sink<int16_t>
{
Q_OBJECT
public:
explicit Schumann(QObject *parent=0)
: sdr::gui::SpectrumProvider(parent), sdr::Sink<int16_t>(),
_buffer_idx(0), _avg_count(0), _buffer(2048), _spectrum(2048),
_spec_count(0), _avg_spectrum(2048), _subsample(0), _Fs(0), _fft(_buffer, sdr::FFT::FORWARD)
{
// init spectrum and buffer
for (size_t i=0; i<2048; i++) {
_buffer[i] = 0;
_spectrum[i] = 0;
}
}
virtual ~Schumann() {
// pass...
}
void config(const sdr::Config &src_cfg) {
// Requires type, sample rate & buffer size
if (!src_cfg.hasType() || !src_cfg.hasSampleRate() || !src_cfg.hasBufferSize()) { return; }
// Check buffer type
if (sdr::Config::typeId< int16_t >() != src_cfg.type()) {
sdr::ConfigError err;
err << "Can not configure Schumann: Invalid type " << src_cfg.type()
<< ", expected " << sdr::Config::typeId<int16_t>();
throw err;
}
// Check input sample rate
double Fs = src_cfg.sampleRate();
if (40 > Fs) {
sdr::ConfigError err;
err << "Can not configure Schumann: Input sample rate too low! The Schumann node requires at "
<< "least a sample rate of 40Hz, got " << Fs << "Hz";
throw err;
}
// Compute subsample
_subsample = Fs/40; _Fs = Fs/_subsample;
}
void process(const sdr::Buffer<int16_t> &buffer, bool allow_overwrite) {
for (size_t i=0; i<buffer.size(); i++) {
// Add value to buffer
_buffer[_buffer_idx] += float(buffer[i])/((1<<15)*_subsample); _avg_count++;
// If subsample count is reached:
if (_avg_count == _subsample) { _buffer_idx++; _avg_count = 0; }
if (_buffer_idx < 2048) { _buffer[_buffer_idx] = 0; }
if (_buffer_idx == 2048) {
// Compute FFT and add to spectrum:
_fft();
_spec_count++;
for (size_t i=0; i<2048; i++) {
_spectrum[i] += _buffer[i].real()*_buffer[i].real() + _buffer[i].imag()*_buffer[i].imag();
_avg_spectrum[i] = 10*(_spectrum[i]/_spec_count);
std::cout << _avg_spectrum[i] << "\t";
}
std::cout << std::endl;
_buffer[0] = 0; _buffer_idx=0;
emit spectrumUpdated();
}
}
}
bool isInputReal() const {
return true;
}
double sampleRate() const {
return _Fs;
}
size_t fftSize() const {
return 2048;
}
const sdr::Buffer<double> &spectrum() const {
return _avg_spectrum;
}
protected:
size_t _buffer_idx;
size_t _avg_count;
sdr::Buffer< std::complex<float> > _buffer;
sdr::Buffer< double > _spectrum;
size_t _spec_count;
sdr::Buffer< double > _avg_spectrum;
size_t _subsample;
double _Fs;
sdr::FFTPlan<float> _fft;
};
#endif // SCHUMANN_HH

@ -0,0 +1,40 @@
#include <libsdr/sdr.hh>
#include <signal.h>
#include <libsdr/gui/gui.hh>
#include <QApplication>
#include <QMainWindow>
#include "schumann.hh"
using namespace sdr;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
sdr::PortAudio::init();
sdr::PortSource<int16_t> src(32000, 1024);
Schumann schumann;
src.connect(&schumann);
QMainWindow *win = new QMainWindow();
sdr::gui::SpectrumView *view = new sdr::gui::SpectrumView(&schumann);
win->setCentralWidget(view);
win->show();
sdr::Queue::get().addIdle(&src, &sdr::PortSource<int16_t>::next);
sdr::Queue::get().start();
app.exec();
sdr::Queue::get().stop();
sdr::Queue::get().wait();
sdr::PortAudio::terminate();
return 0;
}
Loading…
Cancel
Save