Just Intonation  Version 1.3.1 (19)
Explore key-independent dynamically adapting tuning in just intonation
audiooutput.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright 2016-2017 Karolin Stange, Christoph Wick, and Haye Hinrichsen
3  *
4  * This file is part of JustIntonation.
5  *
6  * JustIntonation is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * JustIntonation is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with JustIntonation. If not, see http://www.gnu.org/licenses/.
18  *****************************************************************************/
19 
20 //=============================================================================
21 // Interface for audio output
22 //=============================================================================
23 
24 #include "audiooutput.h"
25 
26 //-----------------------------------------------------------------------------
27 // Constructor, resetting member variables
28 //-----------------------------------------------------------------------------
34 
36  : AudioBase()
37  , mAudioOutputDevice(this)
38  , defaultGenerator()
39  , pAudioGenerator(&defaultGenerator)
40  , mAudioDeviceGuard(this)
41  , mDefaultBufferSize(4096)
42 {
43  setThreadName("AudioOutput");
44 }
45 
46 
47 //-----------------------------------------------------------------------------
48 // Init audio device
49 //-----------------------------------------------------------------------------
53 
55 {
57  return true;
58 }
59 
60 
61 //-----------------------------------------------------------------------------
62 // Start audio device
63 //-----------------------------------------------------------------------------
68 
70 {
74  AudioBase::start(); // Starts the thread
75  return true;
76 }
77 
78 //-----------------------------------------------------------------------------
79 // Initially called worker function in the new thread
80 //-----------------------------------------------------------------------------
85 
86 
88 {
89  LOGMESSAGE << "Starting audio device with previous settings";
90  AudioParameters parameters;
91  parameters.deviceName=mSettings.value("audiooutput/devicename","default").toString();
92  parameters.channelCount=mSettings.value("audiooutput/channelcount",2).toInt();
93  parameters.bufferSize=mSettings.value("audiooutput/buffersize",mDefaultBufferSize).toInt();
94  parameters.sampleRate=mSettings.value("audiooutput/samplerate",44100).toInt();
95  parameters.active=mSettings.value("audiooutput/active",true).toBool();
96  parameters.muted = false;
97  setWantedParameters(parameters);
98  connectDevice(true);
99 }
100 
102 {
103  connectDevice(false);
104 }
105 
106 //-----------------------------------------------------------------------------
107 // Stop audio device
108 //-----------------------------------------------------------------------------
112 
114 {
116  AudioBase::stop();
117  return true;
118 }
119 
120 
121 //-----------------------------------------------------------------------------
122 // Exit audio device
123 //-----------------------------------------------------------------------------
127 
129 {
130  stop();
131  AudioBase::exit();
132  return true;
133 }
134 
135 
136 //-----------------------------------------------------------------------------
137 // Set audio generator
138 //-----------------------------------------------------------------------------
147 
149 {
150  // inform the generator (synthesizer) about the current parameters
152  // attach the gernator to the output
153  pAudioGenerator = &generator;
154 }
155 
156 
157 //-----------------------------------------------------------------------------
158 // Set device parameters
159 //-----------------------------------------------------------------------------
166 
168 {
169  LOGMESSAGE << "Setting parameters for device " << p.deviceName;
173 }
174 
175 
176 //-----------------------------------------------------------------------------
177 // Connect the device
178 //-----------------------------------------------------------------------------
190 
191 void AudioOutput::connectDevice (const bool active)
192 {
193  if (active)
194  {
197  if (actual.active)
198  {
199  LOGMESSAGE << "First disconnect audio device";
200  connectDevice(false);
201  }
202  LOGMESSAGE << "Connect device " << wanted.deviceName;
203  if (mAudioOutputDevice.connect(wanted))
204  {
205  // At this point the audio output device has alread
206  // the actual parameters
207  LOGMESSAGE << "Audio device successfully connected";
208  actual = getActualDeviceParameters();
209  mSettings.setValue("audiooutput/active",actual.active);
210  mSettings.setValue("audiooutput/devicename",actual.deviceName);
211  mSettings.setValue("audiooutput/channelcount",actual.channelCount);
212  mSettings.setValue("audiooutput/buffersize",actual.bufferSize);
213  mSettings.setValue("audiooutput/samplerate",actual.sampleRate);
215  }
216  else
217  {
218  LOGWARNING << "AudioOutputDevice could not be connected, aborting.";
221  }
222  }
223  else
224  {
225  LOGMESSAGE << "Disconnect current device";
227  }
228 }
229 
230 
231 //-----------------------------------------------------------------------------
232 // Update list of devices
233 //-----------------------------------------------------------------------------
237 
239 {
240  LOGSTATUS << "Update list of devices";
241  QList<QAudioDeviceInfo> infoAboutDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
242  QStringList currentDeviceNames;
243  for (const QAudioDeviceInfo &dev : infoAboutDevices)
244  {
245  QString deviceName = dev.deviceName();
246  // Suppress direct hardware entries in Linux ALSA
247  if (not deviceName.contains(":CARD="))
248  {
249  currentDeviceNames.append(deviceName);
250  }
251  }
252  LOGSTATUS << currentDeviceNames;
253 
254  if (currentDeviceNames != mAudioDeviceNames)
255  {
256  LOGMESSAGE << "Recognized a change in the list of audio devices";
257  LOGSTATUS << "The current device names are:" << currentDeviceNames;
258  // Compare the old and the new device list
259  QStringList newDevices,removedDevices;
260  for (const QString &entry : currentDeviceNames)
261  if (mAudioDeviceNames.indexOf(entry)<0) newDevices.append(entry);
262  for (const QString &entry : mAudioDeviceNames)
263  if (currentDeviceNames.indexOf(entry)<0) removedDevices.append(entry);
264 
265  // emit the corresponding signals
266  if (newDevices.size()>0 and mAudioDeviceNames.size()>=0)
267  emit onAudioDevicesAdded(newDevices);
268  if (removedDevices.size()>0)
269  emit onAudioDevicesRemoved(removedDevices);
270 
271  mAudioDeviceNames = currentDeviceNames;
272  emit onChangeOfAvailableAudioDevices(mAudioDeviceNames);
273  }
274 }
275 
276 
277 //-----------------------------------------------------------------------------
278 // Set global volume
279 //-----------------------------------------------------------------------------
284 
285 void AudioOutput::setVolume(double volume)
286 {
287  LOGMESSAGE << "Setting volume to" << volume;
289 }
290 
291 
void disconnect()
Stop the audio output device.
virtual void finallyCalledWorker() override final
Virtual worker function called when the thread stops.
AudioOutput()
Constructor.
Definition: audiooutput.cpp:35
void updateListOfDevices() override final
Update the list of devices.
virtual bool init() override
Init audio device.
Definition: audiooutput.cpp:54
virtual void initiallyCalledWorker() override final
Initially called worker function.
Definition: audiooutput.cpp:87
bool active
True of device is active.
int getVerbosity()
Get verbosity level.
Definition: threadbase.h:80
#define LOGMESSAGE
Definition: log.h:43
void setVerbosity(int verbosity)
Set verbosity level of messages.
Definition: threadbase.cpp:113
QString deviceName
Name of the audio device.
void onConnectionSuccessfullyEstablished(bool success)
Signal indicating that successful of failed connection.
void onAudioDevicesRemoved(const QStringList &devices)
Signal indicating that an audio device has been removed.
bool connect(const AudioDeviceParameters &parameters)
AudioOutputDevice mAudioOutputDevice
Instance of the device.
Definition: audiooutput.h:70
Virtual base class for audio-generating modules.
Structure holding the parameters and status of an audio device.
virtual bool stop() override
Stop audio device.
virtual bool init()
Virtual initialization function (no functionality here)
Definition: threadbase.h:70
void setVolume(double volume)
Set the global volume of the audio device.
void setVerbosity(int verbosity)
Set the verbosity level of the class-specific messages.
Definition: log.cpp:107
int sampleRate
Actual sample rate.
void setAudioGenerator(AudioGenerator &generator)
Select an AudioGenerator for output.
void setParameters(const AudioParameters &parameters)
Set audio device parameters.
const AudioParameters getActualDeviceParameters() const
Get the actual audio device parameters.
Definition: audiobase.cpp:55
void onChangeOfAvailableAudioDevices(const QStringList &devices)
Signal indicating that the list of available devices has been changed.
void onAudioDevicesAdded(const QStringList &devices)
Signal indicating that a new audio device was plugged in (e.g. a USB headphone)
virtual bool exit() override
Exit audio device.
int bufferSize
Buffer size of the device if applicable.
#define LOGSTATUS
Definition: log.h:42
QStringList mAudioDeviceNames
Current list of devices.
Definition: audiobase.h:94
virtual bool exit()
Virtual exit function (no functionality here)
Definition: threadbase.h:71
AudioGenerator * pAudioGenerator
Pointer to synthesizer.
Definition: audiooutput.h:72
void setVolume(double volume)
Set the global volume.
virtual bool start()
Start the thread.
Definition: threadbase.cpp:64
void setActualParameters(const AudioParameters &p)
Set audio device parameters (thread safe)
void connectDevice(const bool active) override final
Connect the audio output to a device (e.g. soundcard) with a given set of device parameters.
int channelCount
Number of channels (mono=1, stereo=2)
void onCurrentDeviceParametersChanged()
Signal indicating that the actually used audio device has changed.
void setThreadName(const QString name)
Set thread name (Linux only)
Definition: threadbase.cpp:121
virtual bool stop()
Stop the thread.
Definition: threadbase.cpp:152
QSettings mSettings
Settings object.
Definition: audiooutput.h:74
void setWantedParameters(const AudioParameters &parameters)
Set the wanted audio device parameters.
Definition: audiobase.cpp:100
bool startMonitoring(int seconds=20)
Start the AudioDeviceGuard.
int mDefaultBufferSize
Default audio buffer size.
Definition: audiooutput.h:77
virtual bool start() override
Start audio device.
Definition: audiooutput.cpp:69
void setActualParameters(const AudioParameters &parameters)
Set the actual audio device parameters.
Definition: audiobase.cpp:85
const AudioParameters getWantedDeviceParameters() const
Get the intended audio device parameters.
Definition: audiobase.cpp:70
Abstract base class for audio input and output.
Definition: audiobase.h:52
AudioDeviceGuard mAudioDeviceGuard
Audio device guard.
Definition: audiooutput.h:73
#define LOGWARNING
Definition: log.h:44
bool muted
True if device is muted.