Added fft windows. (No waterfall windows yet.)
It seems that the code looks much better now, I mean more C++ like.
//============================================================================ // Name : Rig008.cpp //============================================================================ #include "SoundIC7410.h" #include "SoundSoft66.h" #include "MyDrawingArea.h" #include <gtkmm.h> #include <vector> #include <iostream> using namespace std; int main(int argc, char *argv[]) { if (argc != 3) { cout << "Usage example: " << argv[0] << " hw:2,0 hw:1,0 " << endl; return 1; } vector <Sound*> soundlist; soundlist.push_back( new SoundIC7410{argv[1]} ); soundlist.push_back( new SoundSoft66{argv[2]} ); argc = 1; /* just for the next line */ Glib::RefPtr < Gtk::Application > app = Gtk::Application::create(argc, argv, "org.gtkmm.example"); Gtk::Window mywindow; Gtk::VBox mybox; mywindow.set_title("IC-7410 Rig Control Program (C++ version)"); for(auto s : soundlist) { mybox.pack_start( *(new MyDrawingArea{s}), FALSE, FALSE, 0 ); } mywindow.add(mybox); mywindow.show_all(); return app->run(mywindow); }
We have two different types of sound devices (see lines 20-21), IC7410 (I channel only) and Soft66 (I and Q channels).
But in the for loop (see lines 30-32), we just use a pointer s to the base class Sound, which is an abstract class with pure virtual functions.
/* Sound.h */ #ifndef SOUND_H_ #define SOUND_H_ #include "AlsaParams.h" #include <asoundlib.h> class Sound : public AlsaParams { public: Sound(); virtual int get_channels() const = 0; virtual int asound_fftcopy() = 0; virtual ~Sound(); }; #endif /* SOUND_H_ */
The functions in the two derived classes, SoundIC7410 and SoundSoft66, override these virtual functions so that the different characteristics of the devices are treated properly.
/* SoundIC7410.h */ #ifndef SOUNDIC7410_H_ #define SOUNDIC7410_H_ #include "AlsaParams.h" #include "Sound.h" class SoundIC7410: public Sound { public: SoundIC7410(); SoundIC7410(char *s); int get_channels() const override { return 1; } int asound_fftcopy() override; virtual ~SoundIC7410(); }; #endif /* SOUNDIC7410_H_ */
/* SoundIC7410.cpp */ #include "SoundIC7410.h" #include <iostream> using namespace std; SoundIC7410::SoundIC7410() { } SoundIC7410::SoundIC7410(char* s) { sound_device = s; channels = 1; rate = 32000; buffer_size = 32 * 1024; period_size = 8 * 1024; nfft = 4 * 1024; /* IC-7410 */ samples = new signed short[period_size * channels * 2]; audio_signal = new double [period_size * channels * 2]; audio_signal_ffted = new double [nfft]; in_real = new double[nfft]; out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * ( nfft/2 + 1 )*2 ); plan = fftw_plan_dft_r2c_1d(nfft, in_real, out, FFTW_MEASURE); asound_init(); asound_go(); } int SoundIC7410::asound_fftcopy() { for (int i = 0; i < nfft; i++) { in_real[i] = audio_signal[i]; } return 0; } SoundIC7410::~SoundIC7410() { }
The important part is that there are no if nor switch statements to take care of the different types of devices.