-
Notifications
You must be signed in to change notification settings - Fork 0
/
DevMinder.hpp
120 lines (88 loc) · 5.61 KB
/
DevMinder.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef DEVMINDER_HPP
#define DEVMINDER_HPP
#include <string>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <memory>
#include <cmath>
#include <vector>
using namespace std;
#include "Pollable.hpp"
#include "PluginRunner.hpp"
#include "WavFileHeader.hpp"
typedef std::map < string, boost::weak_ptr < Pollable > > RawListenerSet;
typedef std::map < string, boost::weak_ptr < PluginRunner > > PluginRunnerSet;
class DevMinder : public Pollable {
public:
static const int MAX_CHANNELS = 2; // maximum of two channels per device
static const int MAX_DEV_QUIET_TIME = 30; // 30 second maximum quiet time before we decide an device data stream is dry and try restart it
string devName; // path to device (e.g. hw:CARD=V10 for ALSA, or rtlsdr:/tmp/rtlsdr1:3 for rtl_tcp listening on /tmp/rtlsdr1:3
int rate; // sampling rate to supply plugins with
unsigned int hwRate; // sampling rate of hardware device
unsigned int numChan; // number of channels to read from device
unsigned int maxSampleAbs; // maximum absolute value of sample
protected:
PluginRunnerSet plugins; // set of plugins accepting input from this device
RawListenerSet rawListeners; // listeners receiving raw output from this device, if
// any.
long long totalFrames; // total frames seen on this device since start of capture
double startTimestamp; // timestamp device was (most recently) started (-1 if
// never)
double stopTimestamp; // timestamp device was (most recently) stopped or opened
// (-1 if not opened yet)
double lastDataReceived; // time at which data was last received (or at which the
// device was most recently started); used to detect
// random audio stop (e.g. due to hub device reset)
// -1 if never started
bool shouldBeRunning; // should this device be running?
bool stopped; // is this device stopped? (by which we mean not
// streaming USB audio)
int hasError; // if non-zero, the most recent error this device got
// while we polled it? (this would have stopped it)
bool demodFMForRaw; // if true, any rawListeners receive FM-demodulated
// samples (reducing stereo to mono)
float demodFMLastTheta; // value of previous phase angle for FM demodulation (in
// range -pi..pi)
int16_t downSampleFactor; // by what factor do we downsample input audio for raw listeners
int16_t downSampleCount[MAX_CHANNELS]; // count of how many samples we've accumulated since last down sample
int32_t downSampleAccum[MAX_CHANNELS]; // accumulator for downsampling
bool downSampleUseAvg; // if true, downsample by averaging; else downsample by subsampling
std::vector < int16_t > sampleBuf; // buffer to store latest interleaved samples from device
public:
static DevMinder * getDevMinder(const string &devName, int rate, unsigned int numChan, const string &label, double now); // factory method
~DevMinder();
int open(); // return 0 on success, non-zero on error
virtual int hw_open() =0 ; // return 0 on success, non-zero on error
virtual bool hw_is_open() = 0;
void addPluginRunner(std::string &label, boost::shared_ptr < PluginRunner > pr);
void removePluginRunner(std::string &label);
void addRawListener(string &label, int downSampleFactor, bool writeWavHeader = false, bool downSampleUseAvg = false);
void removeRawListener(string &label);
void removeAllRawListeners();
string about();
string toJSON();
virtual int getNumPollFDs ();
virtual int hw_getNumPollFDs () = 0;
virtual int getPollFDs (struct pollfd *pollfds); // return 0 on sucess; non-zero on error
virtual int hw_getPollFDs (struct pollfd *pollfds) = 0; // return 0 on success; non-zero on error
int getOutputFD(){return 0;}; // this kind of Pollable has no output FDs
virtual void handleEvents ( struct pollfd *pollfds, bool timedOut, double timeNow);
virtual int hw_handleEvents ( struct pollfd *pollfds, bool timedOut) = 0; // returns number of frames of data available (possibly 0)
virtual int hw_getFrames (int16_t *buf, int numFrames, double & frameTimestamp) = 0; // fill buffer buf with frame data (interleaved by channel); returns # of frames copied
// it is guaranteed that whenever hw_handleEvents returns a positive number N, hw_getFrames will be called with numFrames=N
// also returns CLOCK_REALTIME for first frame in frameTimestamp
// negative return value is an error code.
int start(double timeNow);
void stop(double timeNow);
void setDemodFMForRaw(bool demod);
protected:
DevMinder(const string &devName, int rate, unsigned int numChan, unsigned int maxSampleAbs, const string &label, double now, int buffSize); // buffSize is in frames.
void delete_privates();
virtual int hw_do_start() = 0; // returns 0 on success; non-zero otherwise
int do_restart(double timeNow);
virtual int hw_do_restart() = 0; // returns 0 on success; non-zero otherwise
virtual int hw_do_stop() = 0; // returns 0 on success; non-zero otherwise
virtual bool hw_running(double timeNow) = 0; // is device running?
};
#endif // DEVMINDER_HPP