1 // Copyright 2005-2019 The Mumble Developers. All rights reserved. 2 // Use of this source code is governed by a BSD-style license 3 // that can be found in the LICENSE file at the root of the 4 // Mumble source tree or at <https://www.mumble.info/LICENSE>. 5 6 #ifndef MUMBLE_MUMBLE_AUDIOOUTPUT_H_ 7 #define MUMBLE_MUMBLE_AUDIOOUTPUT_H_ 8 9 #include <boost/shared_ptr.hpp> 10 #include <QtCore/QObject> 11 #include <QtCore/QThread> 12 13 // AudioOutput depends on User being valid. This means it's important 14 // to removeBuffer from here BEFORE MainWindow gets any UserLeft 15 // messages. Any decendant user should feel free to remove unused 16 // AudioOutputUser objects; it's better to recreate them than 17 // having them use resources while unused. 18 19 #ifndef SPEAKER_FRONT_LEFT 20 #define SPEAKER_FRONT_LEFT 0x1 21 #define SPEAKER_FRONT_RIGHT 0x2 22 #define SPEAKER_FRONT_CENTER 0x4 23 #define SPEAKER_LOW_FREQUENCY 0x8 24 #define SPEAKER_BACK_LEFT 0x10 25 #define SPEAKER_BACK_RIGHT 0x20 26 #define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 27 #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 28 #define SPEAKER_BACK_CENTER 0x100 29 #define SPEAKER_SIDE_LEFT 0x200 30 #define SPEAKER_SIDE_RIGHT 0x400 31 #define SPEAKER_TOP_CENTER 0x800 32 #define SPEAKER_TOP_FRONT_LEFT 0x1000 33 #define SPEAKER_TOP_FRONT_CENTER 0x2000 34 #define SPEAKER_TOP_FRONT_RIGHT 0x4000 35 #define SPEAKER_TOP_BACK_LEFT 0x8000 36 #define SPEAKER_TOP_BACK_CENTER 0x10000 37 #define SPEAKER_TOP_BACK_RIGHT 0x20000 38 #endif 39 40 #include "Audio.h" 41 #include "Message.h" 42 43 class AudioOutput; 44 class ClientUser; 45 class AudioOutputUser; 46 class AudioOutputSample; 47 48 typedef boost::shared_ptr<AudioOutput> AudioOutputPtr; 49 50 class AudioOutputRegistrar { 51 private: 52 Q_DISABLE_COPY(AudioOutputRegistrar) 53 public: 54 static QMap<QString, AudioOutputRegistrar *> *qmNew; 55 static QString current; 56 static AudioOutputPtr newFromChoice(QString choice = QString()); 57 58 const QString name; 59 int priority; 60 61 AudioOutputRegistrar(const QString &n, int priority = 0); 62 virtual ~AudioOutputRegistrar(); 63 virtual AudioOutput *create() = 0; 64 virtual const QList<audioDevice> getDeviceChoices() = 0; 65 virtual void setDeviceChoice(const QVariant &, Settings &) = 0; 66 virtual bool canMuteOthers() const; 67 virtual bool usesOutputDelay() const; 68 virtual bool canExclusive() const; 69 }; 70 71 class AudioOutput : public QThread { 72 private: 73 Q_OBJECT 74 Q_DISABLE_COPY(AudioOutput) 75 private: 76 float *fSpeakers; 77 float *fSpeakerVolume; 78 bool *bSpeakerPositional; 79 protected: 80 enum { SampleShort, SampleFloat } eSampleFormat; 81 volatile bool bRunning; 82 unsigned int iFrameSize; 83 volatile unsigned int iMixerFreq; 84 unsigned int iChannels; 85 unsigned int iSampleSize; 86 QReadWriteLock qrwlOutputs; 87 QMultiHash<const ClientUser *, AudioOutputUser *> qmOutputs; 88 89 virtual void removeBuffer(AudioOutputUser *); 90 void initializeMixer(const unsigned int *chanmasks, bool forceheadphone = false); 91 bool mix(void *output, unsigned int nsamp); 92 public: 93 void wipe(); 94 95 /// Construct an AudioOutput. 96 /// 97 /// This constructor is only ever called by Audio::startOutput(), and is guaranteed 98 /// to be called on the application's main thread. 99 AudioOutput(); 100 101 /// Destroy an AudioOutput. 102 /// 103 /// This destructor is only ever called by Audio::stopOutput() and Audio::stop(), 104 /// and is guaranteed to be called on the application's main thread. 105 ~AudioOutput() Q_DECL_OVERRIDE; 106 107 void addFrameToBuffer(ClientUser *, const QByteArray &, unsigned int iSeq, MessageHandler::UDPMessageType type); 108 void removeBuffer(const ClientUser *); 109 AudioOutputSample *playSample(const QString &filename, bool loop = false); 110 void run() Q_DECL_OVERRIDE = 0; 111 virtual bool isAlive() const; 112 const float *getSpeakerPos(unsigned int &nspeakers); 113 static float calcGain(float dotproduct, float distance); 114 unsigned int getMixerFreq() const; 115 }; 116 117 #endif 118