| 
									
										
										
										
											2013-08-10 15:29:55 +00:00
										 |  |  | #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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 19:29:13 +00:00
										 |  |  |   bool initialize (OpenMode mode, Channel channel); | 
					
						
							| 
									
										
										
										
											2013-08-10 15:29:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-07 00:55:05 +00:00
										 |  |  |   bool isSequential () const override {return true;} | 
					
						
							| 
									
										
										
										
											2013-08-10 15:29:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-28 18:34:27 +00:00
										 |  |  |   void store (char const * source, size_t numFrames, qint16 * dest) | 
					
						
							| 
									
										
										
										
											2013-08-10 15:29:55 +00:00
										 |  |  |   { | 
					
						
							|  |  |  |     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
 |