WSJT-X/AudioDevice.hpp
Bill Somerville 0403b16aac Replaced Detector monitoring switch with audio stream suspend/resume.
In an effort to reduce the processing overhead when transmitting I
have suspended the audio input stream at source instead of the prior
behavior that simply idled skipping received samples.

This is in response to high activity levels, especially with JTAlert
also running, when decode processing rolls over into the next TX
period.

Tests show a reduction in CPU loading from ~5% to ~1.5% in the above
scenario. Hopefully this will reduce the likelyhood of TX audio
glitches when other system activity spikes.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3986 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
2014-04-07 00:55:05 +00:00

99 lines
1.9 KiB
C++

#ifndef AUDIODEVICE_HPP__
#define AUDIODEVICE_HPP__
#include <QIODevice>
class QDataStream;
//
// abstract base class for audio devices
//
class AudioDevice : public QIODevice
{
public:
enum Channel {Mono, Left, Right, Both}; // these are mapped to combobox index so don't change
static char const * toString (Channel c)
{
return Mono == c ? "Mono" : Left == c ? "Left" : Right == c ? "Right" : "Both";
}
static Channel fromString (QString const& str)
{
QString s (str.toCaseFolded ().trimmed ().toLatin1 ());
return "both" == s ? Both : "right" == s ? Right : "left" == s ? Left : Mono;
}
bool initialize (OpenMode mode, Channel channel);
bool isSequential () const override {return true;}
size_t bytesPerFrame () const {return sizeof (qint16) * (Mono == m_channel ? 1 : 2);}
Channel channel () const {return m_channel;}
protected:
AudioDevice (QObject * parent = 0)
: QIODevice (parent)
{
}
void store (char const * source, size_t numFrames, qint16 * dest)
{
qint16 const * begin (reinterpret_cast<qint16 const *> (source));
for ( qint16 const * i = begin; i != begin + numFrames * (bytesPerFrame () / sizeof (qint16)); i += bytesPerFrame () / sizeof (qint16))
{
switch (m_channel)
{
case Mono:
*dest++ = *i;
break;
case Right:
*dest++ = *(i + 1);
break;
case Both: // should be able to happen but if it
// does we'll take left
Q_ASSERT (Both == m_channel);
case Left:
*dest++ = *i;
break;
}
}
}
qint16 * load (qint16 const sample, qint16 * dest)
{
switch (m_channel)
{
case Mono:
*dest++ = sample;
break;
case Left:
*dest++ = sample;
*dest++ = 0;
break;
case Right:
*dest++ = 0;
*dest++ = sample;
break;
case Both:
*dest++ = sample;
*dest++ = sample;
break;
}
return dest;
}
private:
Channel m_channel;
};
Q_DECLARE_METATYPE (AudioDevice::Channel);
#endif