SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Public Types | Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
AudioOutput Class Reference

#include <audiooutput.h>

Inherits QIODevice.

+ Collaboration diagram for AudioOutput:

Public Types

enum  UDPChannelMode { UDPChannelLeft, UDPChannelRight, UDPChannelMixed, UDPChannelStereo }
 
enum  UDPChannelCodec {
  UDPCodecL16, UDPCodecL8, UDPCodecALaw, UDPCodecULaw,
  UDPCodecG722, UDPCodecOpus
}
 

Public Member Functions

 AudioOutput ()
 
virtual ~AudioOutput ()
 
bool start (int device, int rate)
 
void stop ()
 
void addFifo (AudioFifo *audioFifo)
 
void removeFifo (AudioFifo *audioFifo)
 
int getNbFifos () const
 
unsigned int getRate () const
 
void setOnExit (bool onExit)
 
void setUdpDestination (const QString &address, uint16_t port)
 
void setUdpCopyToUDP (bool copyToUDP)
 
void setUdpUseRTP (bool useRTP)
 
void setUdpChannelMode (UDPChannelMode udpChannelMode)
 
void setUdpChannelFormat (UDPChannelCodec udpChannelCodec, bool stereo, int sampleRate)
 
void setUdpDecimation (uint32_t decimation)
 

Private Member Functions

virtual qint64 readData (char *data, qint64 maxLen)
 
virtual qint64 writeData (const char *data, qint64 len)
 

Private Attributes

QMutex m_mutex
 
QAudioOutput * m_audioOutput
 
AudioNetSinkm_audioNetSink
 
bool m_copyAudioToUdp
 
UDPChannelMode m_udpChannelMode
 
UDPChannelCodec m_udpChannelCodec
 
uint m_audioUsageCount
 
bool m_onExit
 
std::list< AudioFifo * > m_audioFifos
 
std::vector< qint32 > m_mixBuffer
 
QAudioFormat m_audioFormat
 

Friends

class AudioOutputPipe
 

Detailed Description

Definition at line 35 of file audiooutput.h.

Member Enumeration Documentation

◆ UDPChannelCodec

Enumerator
UDPCodecL16 

Linear 16 bit (no codec)

UDPCodecL8 

Linear 8 bit.

UDPCodecALaw 

PCM A-law 8 bit.

UDPCodecULaw 

PCM Mu-law 8 bit.

UDPCodecG722 

G722 compression.

UDPCodecOpus 

Opus compression.

Definition at line 45 of file audiooutput.h.

46  {
47  UDPCodecL16,
48  UDPCodecL8,
49  UDPCodecALaw,
50  UDPCodecULaw,
51  UDPCodecG722,
53  };
Opus compression.
Definition: audiooutput.h:52
Linear 16 bit (no codec)
Definition: audiooutput.h:47
G722 compression.
Definition: audiooutput.h:51
Linear 8 bit.
Definition: audiooutput.h:48
PCM A-law 8 bit.
Definition: audiooutput.h:49
PCM Mu-law 8 bit.
Definition: audiooutput.h:50

◆ UDPChannelMode

Enumerator
UDPChannelLeft 
UDPChannelRight 
UDPChannelMixed 
UDPChannelStereo 

Definition at line 37 of file audiooutput.h.

Constructor & Destructor Documentation

◆ AudioOutput()

AudioOutput::AudioOutput ( )

Definition at line 27 of file audiooutput.cpp.

27  :
28  m_mutex(QMutex::Recursive),
29  m_audioOutput(0),
30  m_audioNetSink(0),
31  m_copyAudioToUdp(false),
35  m_onExit(false),
36  m_audioFifos()
37 {
38 }
bool m_copyAudioToUdp
Definition: audiooutput.h:79
QAudioOutput * m_audioOutput
Definition: audiooutput.h:77
std::list< AudioFifo * > m_audioFifos
Definition: audiooutput.h:85
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
QMutex m_mutex
Definition: audiooutput.h:76
uint m_audioUsageCount
Definition: audiooutput.h:82
bool m_onExit
Definition: audiooutput.h:83
Linear 16 bit (no codec)
Definition: audiooutput.h:47
UDPChannelCodec m_udpChannelCodec
Definition: audiooutput.h:81
UDPChannelMode m_udpChannelMode
Definition: audiooutput.h:80

◆ ~AudioOutput()

AudioOutput::~AudioOutput ( )
virtual

Definition at line 40 of file audiooutput.cpp.

41 {
42 // stop();
43 //
44 // QMutexLocker mutexLocker(&m_mutex);
45 //
46 // for (std::list<AudioFifo*>::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it)
47 // {
48 // delete *it;
49 // }
50 //
51 // m_audioFifos.clear();
52 }

Member Function Documentation

◆ addFifo()

void AudioOutput::addFifo ( AudioFifo audioFifo)

Definition at line 160 of file audiooutput.cpp.

References m_audioFifos, and m_mutex.

161 {
162  QMutexLocker mutexLocker(&m_mutex);
163 
164  m_audioFifos.push_back(audioFifo);
165 }
std::list< AudioFifo * > m_audioFifos
Definition: audiooutput.h:85
QMutex m_mutex
Definition: audiooutput.h:76

◆ getNbFifos()

int AudioOutput::getNbFifos ( ) const
inline

Definition at line 63 of file audiooutput.h.

63 { return m_audioFifos.size(); }
std::list< AudioFifo * > m_audioFifos
Definition: audiooutput.h:85

◆ getRate()

unsigned int AudioOutput::getRate ( ) const
inline

Definition at line 65 of file audiooutput.h.

Referenced by AudioDeviceManager::setOutputDeviceInfo().

65 { return m_audioFormat.sampleRate(); }
QAudioFormat m_audioFormat
Definition: audiooutput.h:88
+ Here is the caller graph for this function:

◆ readData()

qint64 AudioOutput::readData ( char *  data,
qint64  maxLen 
)
privatevirtual

Definition at line 221 of file audiooutput.cpp.

References i, m_audioFifos, m_audioNetSink, m_copyAudioToUdp, m_mixBuffer, m_udpChannelMode, UDPChannelLeft, UDPChannelMixed, UDPChannelRight, UDPChannelStereo, and AudioNetSink::write().

222 {
223  //qDebug("AudioOutput::readData: %lld", maxLen);
224 
225  // Study this mutex on OSX, for now deadlocks possible
226  // Removed as it may indeed cause lockups and is in fact useless.
227 //#ifndef __APPLE__
228 // QMutexLocker mutexLocker(&m_mutex);
229 //#endif
230 
231  unsigned int samplesPerBuffer = maxLen / 4;
232 
233  if (samplesPerBuffer == 0)
234  {
235  return 0;
236  }
237 
238  if (m_mixBuffer.size() < samplesPerBuffer * 2)
239  {
240  m_mixBuffer.resize(samplesPerBuffer * 2); // allocate 2 qint32 per sample (stereo)
241 
242  if (m_mixBuffer.size() != samplesPerBuffer * 2)
243  {
244  return 0;
245  }
246  }
247 
248  memset(&m_mixBuffer[0], 0x00, 2 * samplesPerBuffer * sizeof(m_mixBuffer[0])); // start with silence
249 
250  // sum up a block from all fifos
251 
252  for (std::list<AudioFifo*>::iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it)
253  {
254  // use outputBuffer as temp - yes, one memcpy could be saved
255  unsigned int samples = (*it)->read((quint8*) data, samplesPerBuffer);
256  const qint16* src = (const qint16*) data;
257  std::vector<qint32>::iterator dst = m_mixBuffer.begin();
258 
259 // if (samples != framesPerBuffer)
260 // {
261 // qDebug("AudioOutput::readData: read %d samples vs %d requested", samples, framesPerBuffer);
262 // }
263 
264  for (unsigned int i = 0; i < samples; i++)
265  {
266  *dst += *src;
267  ++src;
268  ++dst;
269  *dst += *src;
270  ++src;
271  ++dst;
272  }
273  }
274  // convert to int16
275 
276  //std::vector<qint32>::const_iterator src = m_mixBuffer.begin(); // Valgrind optim
277  qint16* dst = (qint16*) data;
278  qint32 sl, sr;
279 
280  for (unsigned int i = 0; i < samplesPerBuffer; i++)
281  {
282  // left channel
283 
284  //s = *src++; // Valgrind optim
285  sl = m_mixBuffer[2*i];
286 
287  if(sl < -32768)
288  {
289  sl = -32768;
290  }
291  else if (sl > 32767)
292  {
293  sl = 32767;
294  }
295 
296  *dst++ = sl;
297 
298  // right channel
299 
300  //s = *src++; // Valgrind optim
301  sr = m_mixBuffer[2*i + 1];
302 
303  if(sr < -32768)
304  {
305  sr = -32768;
306  }
307  else if (sr > 32767)
308  {
309  sr = 32767;
310  }
311 
312  *dst++ = sr;
313 
314  if ((m_copyAudioToUdp) && (m_audioNetSink))
315  {
316  switch (m_udpChannelMode)
317  {
318  case UDPChannelStereo:
319  m_audioNetSink->write(sl, sr);
320  break;
321  case UDPChannelMixed:
322  m_audioNetSink->write((sl+sr)/2);
323  break;
324  case UDPChannelRight:
325  m_audioNetSink->write(sr);
326  break;
327  case UDPChannelLeft:
328  default:
329  m_audioNetSink->write(sl);
330  break;
331  }
332  }
333  }
334 
335  return samplesPerBuffer * 4;
336 }
bool m_copyAudioToUdp
Definition: audiooutput.h:79
std::list< AudioFifo * > m_audioFifos
Definition: audiooutput.h:85
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
std::vector< qint32 > m_mixBuffer
Definition: audiooutput.h:86
int32_t i
Definition: decimators.h:244
void write(qint16 sample)
UDPChannelMode m_udpChannelMode
Definition: audiooutput.h:80
+ Here is the call graph for this function:

◆ removeFifo()

void AudioOutput::removeFifo ( AudioFifo audioFifo)

Definition at line 167 of file audiooutput.cpp.

References m_audioFifos, and m_mutex.

168 {
169  QMutexLocker mutexLocker(&m_mutex);
170 
171  m_audioFifos.remove(audioFifo);
172 }
std::list< AudioFifo * > m_audioFifos
Definition: audiooutput.h:85
QMutex m_mutex
Definition: audiooutput.h:76

◆ setOnExit()

void AudioOutput::setOnExit ( bool  onExit)
inline

Definition at line 66 of file audiooutput.h.

References decimation().

66 { m_onExit = onExit; }
bool m_onExit
Definition: audiooutput.h:83
+ Here is the call graph for this function:

◆ setUdpChannelFormat()

void AudioOutput::setUdpChannelFormat ( UDPChannelCodec  udpChannelCodec,
bool  stereo,
int  sampleRate 
)

Definition at line 205 of file audiooutput.cpp.

References m_audioNetSink, m_udpChannelCodec, and AudioNetSink::setParameters().

Referenced by AudioDeviceManager::setOutputDeviceInfo().

206 {
207  m_udpChannelCodec = udpChannelCodec;
208 
209  if (m_audioNetSink) {
211  }
212 }
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
UDPChannelCodec m_udpChannelCodec
Definition: audiooutput.h:81
void setParameters(Codec codec, bool stereo, int sampleRate)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setUdpChannelMode()

void AudioOutput::setUdpChannelMode ( UDPChannelMode  udpChannelMode)

Definition at line 200 of file audiooutput.cpp.

References m_udpChannelMode.

Referenced by AudioDeviceManager::setOutputDeviceInfo().

201 {
202  m_udpChannelMode = udpChannelMode;
203 }
UDPChannelMode m_udpChannelMode
Definition: audiooutput.h:80
+ Here is the caller graph for this function:

◆ setUdpCopyToUDP()

void AudioOutput::setUdpCopyToUDP ( bool  copyToUDP)

Definition at line 188 of file audiooutput.cpp.

References m_copyAudioToUdp.

Referenced by AudioDeviceManager::setOutputDeviceInfo().

189 {
190  m_copyAudioToUdp = copyToUDP;
191 }
bool m_copyAudioToUdp
Definition: audiooutput.h:79
+ Here is the caller graph for this function:

◆ setUdpDecimation()

void AudioOutput::setUdpDecimation ( uint32_t  decimation)

Definition at line 214 of file audiooutput.cpp.

References m_audioNetSink, and AudioNetSink::setDecimation().

Referenced by AudioDeviceManager::setOutputDeviceInfo().

215 {
216  if (m_audioNetSink) {
218  }
219 }
void setDecimation(uint32_t decimation)
int decimation(float Fin, float Fout)
Definition: datvdemod.h:66
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setUdpDestination()

void AudioOutput::setUdpDestination ( const QString &  address,
uint16_t  port 
)

Definition at line 181 of file audiooutput.cpp.

References m_audioNetSink, and AudioNetSink::setDestination().

Referenced by AudioDeviceManager::setOutputDeviceInfo().

182 {
183  if (m_audioNetSink) {
184  m_audioNetSink->setDestination(address, port);
185  }
186 }
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
void setDestination(const QString &address, uint16_t port)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setUdpUseRTP()

void AudioOutput::setUdpUseRTP ( bool  useRTP)

Definition at line 193 of file audiooutput.cpp.

References m_audioNetSink, AudioNetSink::selectType(), AudioNetSink::SinkRTP, and AudioNetSink::SinkUDP.

Referenced by AudioDeviceManager::setOutputDeviceInfo().

194 {
195  if (m_audioNetSink) {
197  }
198 }
bool selectType(SinkType type)
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ start()

bool AudioOutput::start ( int  device,
int  rate 
)

Definition at line 54 of file audiooutput.cpp.

References m_audioFormat, m_audioNetSink, m_audioOutput, and m_mutex.

Referenced by AudioDeviceManager::setOutputDeviceInfo().

55 {
56 
57 // if (m_audioUsageCount == 0)
58 // {
59  QMutexLocker mutexLocker(&m_mutex);
60  QAudioDeviceInfo devInfo;
61 
62  if (device < 0)
63  {
64  devInfo = QAudioDeviceInfo::defaultOutputDevice();
65  qWarning("AudioOutput::start: using system default device %s", qPrintable(devInfo.defaultOutputDevice().deviceName()));
66  }
67  else
68  {
69  QList<QAudioDeviceInfo> devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
70 
71  if (device < devicesInfo.size())
72  {
73  devInfo = devicesInfo[device];
74  qWarning("AudioOutput::start: using audio device #%d: %s", device, qPrintable(devInfo.deviceName()));
75  }
76  else
77  {
78  devInfo = QAudioDeviceInfo::defaultOutputDevice();
79  qWarning("AudioOutput::start: audio device #%d does not exist. Using system default device %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName()));
80  }
81  }
82 
83  //QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice());
84 
85  m_audioFormat.setSampleRate(rate);
86  m_audioFormat.setChannelCount(2);
87  m_audioFormat.setSampleSize(16);
88  m_audioFormat.setCodec("audio/pcm");
89  m_audioFormat.setByteOrder(QAudioFormat::LittleEndian);
90  m_audioFormat.setSampleType(QAudioFormat::SignedInt);
91 
92  if (!devInfo.isFormatSupported(m_audioFormat))
93  {
94  m_audioFormat = devInfo.nearestFormat(m_audioFormat);
95  std::ostringstream os;
96  os << " sampleRate: " << m_audioFormat.sampleRate()
97  << " channelCount: " << m_audioFormat.channelCount()
98  << " sampleSize: " << m_audioFormat.sampleSize()
99  << " codec: " << m_audioFormat.codec().toStdString()
100  << " byteOrder: " << (m_audioFormat.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE")
101  << " sampleType: " << (int) m_audioFormat.sampleType();
102  qWarning("AudioOutput::start: format %d Hz 2xS16LE audio/pcm not supported. Using: %s", rate, os.str().c_str());
103  }
104  else
105  {
106  qInfo("AudioOutput::start: audio format OK");
107  }
108 
109  if (m_audioFormat.sampleSize() != 16)
110  {
111  qWarning("AudioOutput::start: Audio device '%s' failed", qPrintable(devInfo.defaultOutputDevice().deviceName()));
112  return false;
113  }
114 
115  m_audioOutput = new QAudioOutput(devInfo, m_audioFormat);
116  m_audioNetSink = new AudioNetSink(0, m_audioFormat.sampleRate(), false);
117 
118  QIODevice::open(QIODevice::ReadOnly);
119 
120  m_audioOutput->start(this);
121 
122  if (m_audioOutput->state() != QAudio::ActiveState)
123  {
124  qWarning("AudioOutput::start: cannot start");
125  }
126 // }
127 //
128 // m_audioUsageCount++;
129 
130  return true;
131 }
QAudioFormat m_audioFormat
Definition: audiooutput.h:88
QAudioOutput * m_audioOutput
Definition: audiooutput.h:77
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
QMutex m_mutex
Definition: audiooutput.h:76
+ Here is the caller graph for this function:

◆ stop()

void AudioOutput::stop ( )

Definition at line 133 of file audiooutput.cpp.

References m_audioNetSink, m_audioOutput, and m_mutex.

Referenced by AudioDeviceManager::setOutputDeviceInfo().

134 {
135  qDebug("AudioOutput::stop");
136 
137  QMutexLocker mutexLocker(&m_mutex);
138  m_audioOutput->stop();
139  QIODevice::close();
140  delete m_audioNetSink;
141  m_audioNetSink = 0;
142  delete m_audioOutput;
143 
144 // if (m_audioUsageCount > 0)
145 // {
146 // m_audioUsageCount--;
147 //
148 // if (m_audioUsageCount == 0)
149 // {
150 // QMutexLocker mutexLocker(&m_mutex);
151 // QIODevice::close();
152 //
153 // if (!m_onExit) {
154 // delete m_audioOutput;
155 // }
156 // }
157 // }
158 }
QAudioOutput * m_audioOutput
Definition: audiooutput.h:77
AudioNetSink * m_audioNetSink
Definition: audiooutput.h:78
QMutex m_mutex
Definition: audiooutput.h:76
+ Here is the caller graph for this function:

◆ writeData()

qint64 AudioOutput::writeData ( const char *  data,
qint64  len 
)
privatevirtual

Definition at line 338 of file audiooutput.cpp.

339 {
340  Q_UNUSED(data);
341  Q_UNUSED(len);
342  return 0;
343 }

Friends And Related Function Documentation

◆ AudioOutputPipe

friend class AudioOutputPipe
friend

Definition at line 94 of file audiooutput.h.

Member Data Documentation

◆ m_audioFifos

std::list<AudioFifo*> AudioOutput::m_audioFifos
private

Definition at line 85 of file audiooutput.h.

Referenced by addFifo(), readData(), and removeFifo().

◆ m_audioFormat

QAudioFormat AudioOutput::m_audioFormat
private

Definition at line 88 of file audiooutput.h.

Referenced by start().

◆ m_audioNetSink

AudioNetSink* AudioOutput::m_audioNetSink
private

◆ m_audioOutput

QAudioOutput* AudioOutput::m_audioOutput
private

Definition at line 77 of file audiooutput.h.

Referenced by start(), and stop().

◆ m_audioUsageCount

uint AudioOutput::m_audioUsageCount
private

Definition at line 82 of file audiooutput.h.

◆ m_copyAudioToUdp

bool AudioOutput::m_copyAudioToUdp
private

Definition at line 79 of file audiooutput.h.

Referenced by readData(), and setUdpCopyToUDP().

◆ m_mixBuffer

std::vector<qint32> AudioOutput::m_mixBuffer
private

Definition at line 86 of file audiooutput.h.

Referenced by readData().

◆ m_mutex

QMutex AudioOutput::m_mutex
private

Definition at line 76 of file audiooutput.h.

Referenced by addFifo(), removeFifo(), start(), and stop().

◆ m_onExit

bool AudioOutput::m_onExit
private

Definition at line 83 of file audiooutput.h.

◆ m_udpChannelCodec

UDPChannelCodec AudioOutput::m_udpChannelCodec
private

Definition at line 81 of file audiooutput.h.

Referenced by setUdpChannelFormat().

◆ m_udpChannelMode

UDPChannelMode AudioOutput::m_udpChannelMode
private

Definition at line 80 of file audiooutput.h.

Referenced by readData(), and setUdpChannelMode().


The documentation for this class was generated from the following files: