1 #ifndef AUDIODEVICE_HPP__ 2 #define AUDIODEVICE_HPP__ 3 4 #include <QIODevice> 5 6 class QDataStream; 7 8 // 9 // abstract base class for audio devices 10 // 11 class AudioDevice : public QIODevice 12 { 13 public: 14 enum Channel {Mono, Left, Right, Both}; // these are mapped to combobox index so don't change 15 toString(Channel c)16 static char const * toString (Channel c) 17 { 18 return Mono == c ? "Mono" : Left == c ? "Left" : Right == c ? "Right" : "Both"; 19 } 20 fromString(QString const & str)21 static Channel fromString (QString const& str) 22 { 23 QString s (str.toCaseFolded ().trimmed ().toLatin1 ()); 24 return "both" == s ? Both : "right" == s ? Right : "left" == s ? Left : Mono; 25 } 26 27 bool initialize (OpenMode mode, Channel channel); 28 isSequential() const29 bool isSequential () const override {return true;} 30 bytesPerFrame() const31 size_t bytesPerFrame () const {return sizeof (qint16) * (Mono == m_channel ? 1 : 2);} 32 channel() const33 Channel channel () const {return m_channel;} 34 35 protected: AudioDevice(QObject * parent=nullptr)36 AudioDevice (QObject * parent = nullptr) 37 : QIODevice {parent} 38 { 39 } 40 store(char const * source,size_t numFrames,qint16 * dest)41 void store (char const * source, size_t numFrames, qint16 * dest) 42 { 43 qint16 const * begin (reinterpret_cast<qint16 const *> (source)); 44 for ( qint16 const * i = begin; i != begin + numFrames * (bytesPerFrame () / sizeof (qint16)); i += bytesPerFrame () / sizeof (qint16)) 45 { 46 switch (m_channel) 47 { 48 case Mono: 49 *dest++ = *i; 50 break; 51 52 case Right: 53 *dest++ = *(i + 1); 54 break; 55 56 case Both: // should be able to happen but if it 57 // does we'll take left 58 Q_ASSERT (Both == m_channel); 59 case Left: 60 *dest++ = *i; 61 break; 62 } 63 } 64 } 65 load(qint16 const sample,qint16 * dest)66 qint16 * load (qint16 const sample, qint16 * dest) 67 { 68 switch (m_channel) 69 { 70 case Mono: 71 *dest++ = sample; 72 break; 73 74 case Left: 75 *dest++ = sample; 76 *dest++ = 0; 77 break; 78 79 case Right: 80 *dest++ = 0; 81 *dest++ = sample; 82 break; 83 84 case Both: 85 *dest++ = sample; 86 *dest++ = sample; 87 break; 88 } 89 return dest; 90 } 91 92 private: 93 Channel m_channel; 94 }; 95 96 Q_DECLARE_METATYPE (AudioDevice::Channel); 97 98 #endif 99