mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-18 10:01:57 -05:00
3fbf5a5686
The filter used for 4 times down-sampling cannot handle sample streams where the hardware or drivers deliver chunks of data that are not multiples of 4 frames long. This seems to be prevalent on some Linux platforms. Also de-interleaving of single channel audio from stereo streams was no longer supported. I have changed the input strategy to de-interleave the incoming sample stream into an intermediate buffer large enough to hold all the samples required for a single unit of processing (one basic waterfall interval) and apply the down-sampling filter to the whole intermediate buffer just prior dispatch to the FFT generator. This now means that we are now using the ubiquitous 48kHz hardware sample rate for both input and output of audio across all platforms and decoding a single channel of a stereo stream is again supported. The down-sampling to 12kHz is done with a high quality FIR 49-tap low pass filter specifically designed by Joe (K1JT) for operation in a 4kHz bandwidth. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3585 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
67 lines
1.9 KiB
C++
67 lines
1.9 KiB
C++
#ifndef DETECTOR_HPP__
|
|
#define DETECTOR_HPP__
|
|
|
|
#include "AudioDevice.hpp"
|
|
|
|
#include <QScopedArrayPointer>
|
|
|
|
//
|
|
// output device that distributes data in predefined chunks via a signal
|
|
//
|
|
// the underlying device for this abstraction is just the buffer that
|
|
// stores samples throughout a receiving period
|
|
//
|
|
class Detector : public AudioDevice
|
|
{
|
|
Q_OBJECT;
|
|
|
|
Q_PROPERTY (bool monitoring READ isMonitoring WRITE setMonitoring);
|
|
|
|
public:
|
|
//
|
|
// if the data buffer were not global storage and fixed size then we
|
|
// might want maximum size passed as constructor arguments
|
|
//
|
|
// we down sample by a factor of 4
|
|
//
|
|
// the framesPerSignal argument is the number after down sampling
|
|
//
|
|
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned framesPerSignal, QObject * parent = 0);
|
|
|
|
bool isMonitoring () const {return m_monitoring;}
|
|
|
|
protected:
|
|
qint64 readData (char * /* data */, qint64 /* maxSize */)
|
|
{
|
|
return -1; // we don't produce data
|
|
}
|
|
|
|
qint64 writeData (char const * data, qint64 maxSize);
|
|
|
|
private:
|
|
// these are private because we want thread safety, must be called via Qt queued connections
|
|
Q_SLOT void open (AudioDevice::Channel channel = Mono) {AudioDevice::open (QIODevice::WriteOnly, channel);}
|
|
Q_SLOT void setMonitoring (bool newState) {m_monitoring = newState; m_bufferPos = 0;}
|
|
Q_SLOT bool reset ();
|
|
Q_SLOT void close () {AudioDevice::close ();}
|
|
|
|
Q_SIGNAL void framesWritten (qint64);
|
|
|
|
void clear (); // discard buffer contents
|
|
unsigned secondInPeriod () const;
|
|
|
|
unsigned m_frameRate;
|
|
unsigned m_period;
|
|
qint32 m_framesPerSignal; // after down sampling
|
|
bool volatile m_monitoring;
|
|
bool m_starting;
|
|
QScopedArrayPointer<short> m_buffer; // de-interleaved sample buffer
|
|
// big enough for all the
|
|
// samples for one increment of
|
|
// data (a signals worth) at
|
|
// the input sample rate
|
|
unsigned m_bufferPos;
|
|
};
|
|
|
|
#endif
|