Skip to content

Commit 6cf2723

Browse files
committed
Added sound settings in Audio>Settings + Moved sound duration in the settings + Added option to change audio output device
1 parent 595d403 commit 6cf2723

21 files changed

+1136
-132
lines changed

ActionAudioDevice.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2021 Benoit Pelletier
3+
*
4+
* This file is part of Sound Generator.
5+
*
6+
* Sound Generator is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Sound Generator is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Sound Generator. If not, see <https://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#include "ActionAudioDevice.h"
22+
#include <QtCore>
23+
#include <QAudioDeviceInfo>
24+
25+
void DebugLogDeviceInfo(const QAudioDeviceInfo& _info)
26+
{
27+
qDebug() << "Device: " << _info.deviceName()
28+
<< " | samples rates: " << _info.supportedSampleRates()
29+
<< " | channel count: " << _info.supportedChannelCounts()
30+
<< " | samples size: " << _info.supportedSampleSizes()
31+
<< " | codecs: " << _info.supportedCodecs()
32+
<< " | byte orders: " << _info.supportedByteOrders()
33+
<< " | sample types: " << _info.supportedSampleTypes();
34+
}
35+
36+
ActionAudioDevice::ActionAudioDevice(const QString& _title, QWidget* _parent)
37+
: QMenu(_title, _parent)
38+
{
39+
connect(this, &QMenu::aboutToShow, this, &ActionAudioDevice::beforeShowing);
40+
connect(this, &QMenu::triggered, this, &ActionAudioDevice::onTriggered);
41+
42+
m_currentInfo = QAudioDeviceInfo::defaultOutputDevice();
43+
DebugLogDeviceInfo(m_currentInfo);
44+
}
45+
46+
void ActionAudioDevice::beforeShowing()
47+
{
48+
clear();
49+
50+
const QList<QAudioDeviceInfo> deviceList = _listAvalaibleDevices();
51+
for(QAudioDeviceInfo device : deviceList)
52+
{
53+
QVariant data;
54+
data.setValue(device);
55+
56+
QAction* act = new QAction(device.deviceName(), this);
57+
act->setCheckable(true);
58+
act->setChecked(device == m_currentInfo);
59+
if(device == m_currentInfo)
60+
{
61+
DebugLogDeviceInfo(device);
62+
}
63+
64+
act->setData(data);
65+
addAction(act);
66+
}
67+
}
68+
69+
void ActionAudioDevice::onTriggered(QAction* _action)
70+
{
71+
QAudioDeviceInfo info = qvariant_cast<QAudioDeviceInfo>(_action->data());
72+
qDebug() << "Clicked on action!";
73+
DebugLogDeviceInfo(info);
74+
if(info != m_currentInfo)
75+
{
76+
m_currentInfo = info;
77+
emit deviceChanged(info);
78+
}
79+
}
80+
81+
const QList<QAudioDeviceInfo> ActionAudioDevice::_listAvalaibleDevices()
82+
{
83+
QMap<QString, QAudioDeviceInfo> infoMap;
84+
QList<QAudioDeviceInfo> deviceList = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
85+
for(QAudioDeviceInfo device : deviceList)
86+
{
87+
QMap<QString, QAudioDeviceInfo>::iterator it = infoMap.find(device.deviceName());
88+
if(it != infoMap.end())
89+
{
90+
int score = 0;
91+
score += (device.supportedSampleRates().count() > it->supportedSampleRates().count())
92+
? 1 : -1;
93+
score += (device.supportedSampleSizes().count() > it->supportedSampleSizes().count())
94+
? 1 : -1;
95+
score += (device.supportedChannelCounts().count() > it->supportedChannelCounts().count())
96+
? 1 : -1;
97+
98+
if(score > 0)
99+
{
100+
infoMap[device.deviceName()] = device;
101+
}
102+
}
103+
else
104+
{
105+
infoMap.insert(device.deviceName(), device);
106+
}
107+
108+
}
109+
return infoMap.values();
110+
}

ActionAudioDevice.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2021 Benoit Pelletier
3+
*
4+
* This file is part of Sound Generator.
5+
*
6+
* Sound Generator is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Sound Generator is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Sound Generator. If not, see <https://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#ifndef ACTIONAUDIODEVICE_H
22+
#define ACTIONAUDIODEVICE_H
23+
24+
#include <QMenu>
25+
#include <QAudioDeviceInfo>
26+
27+
class ActionAudioDevice : public QMenu
28+
{
29+
Q_OBJECT
30+
31+
public:
32+
ActionAudioDevice(const QString& _title, QWidget* _parent = nullptr);
33+
34+
signals:
35+
void deviceChanged(const QAudioDeviceInfo& _info);
36+
37+
private slots:
38+
void beforeShowing();
39+
void onTriggered(QAction* _action);
40+
41+
private:
42+
static const QList<QAudioDeviceInfo> _listAvalaibleDevices();
43+
44+
private:
45+
QAudioDeviceInfo m_currentInfo;
46+
};
47+
48+
#endif // ACTIONAUDIODEVICE_H

AudioSettings.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2021 Benoit Pelletier
3+
*
4+
* This file is part of Sound Generator.
5+
*
6+
* Sound Generator is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Sound Generator is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Sound Generator. If not, see <https://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#include "AudioSettings.h"
22+
#include "Signal.h"
23+
#include "Utils.h"
24+
#include <QtDebug>
25+
#include <QJsonValue>
26+
27+
#define SAMPLE_RATE_LABEL "sampleRate"
28+
#define SAMPLE_SIZE_LABEL "sampleSize"
29+
#define CHANNEL_COUNT_LABEL "channelCount"
30+
#define DURATION_LABEL "duration"
31+
32+
AudioSettings::AudioSettings()
33+
: m_duration(0.0), m_sampleRate(0), m_channelCount(0), m_sampleSize(0)
34+
{
35+
}
36+
37+
void AudioSettings::setSampleRate(int _sampleRate)
38+
{
39+
if(m_sampleRate != _sampleRate)
40+
{
41+
m_sampleRate = _sampleRate;
42+
m_isDirty = true;
43+
}
44+
}
45+
46+
void AudioSettings::setSampleSize(int _sampleSize)
47+
{
48+
if(m_sampleSize != _sampleSize)
49+
{
50+
m_sampleSize = _sampleSize;
51+
m_isDirty = true;
52+
}
53+
}
54+
55+
void AudioSettings::setChannelCount(int _channelCount)
56+
{
57+
if(m_channelCount != _channelCount)
58+
{
59+
m_channelCount = _channelCount;
60+
m_isDirty = true;
61+
}
62+
}
63+
64+
QJsonObject AudioSettings::toJson() const
65+
{
66+
QJsonObject json;
67+
json[SAMPLE_RATE_LABEL] = m_sampleRate;
68+
json[SAMPLE_SIZE_LABEL] = m_sampleSize;
69+
json[CHANNEL_COUNT_LABEL] = m_channelCount;
70+
json[DURATION_LABEL] = m_duration;
71+
72+
return json;
73+
}
74+
75+
void AudioSettings::fromJson(const QJsonObject& json, const int version)
76+
{
77+
if(Utils::CheckJsonValue(json, SAMPLE_RATE_LABEL, QJsonValue::Double, 200))
78+
m_sampleRate = json[SAMPLE_RATE_LABEL].toInt();
79+
if(Utils::CheckJsonValue(json, SAMPLE_SIZE_LABEL, QJsonValue::Double, 210))
80+
m_sampleSize = json[SAMPLE_SIZE_LABEL].toInt();
81+
if(Utils::CheckJsonValue(json, CHANNEL_COUNT_LABEL, QJsonValue::Double, 220))
82+
m_channelCount = json[CHANNEL_COUNT_LABEL].toInt();
83+
if(version >= 2)
84+
{
85+
if(Utils::CheckJsonValue(json, DURATION_LABEL, QJsonValue::Double, 230))
86+
m_duration = json[DURATION_LABEL].toDouble();
87+
}
88+
m_isDirty = true;
89+
}

AudioSettings.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2021 Benoit Pelletier
3+
*
4+
* This file is part of Sound Generator.
5+
*
6+
* Sound Generator is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Sound Generator is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Sound Generator. If not, see <https://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#ifndef AUDIOSETTINGS_H
22+
#define AUDIOSETTINGS_H
23+
24+
#include <QAudioOutput>
25+
#include <QJsonObject>
26+
27+
class Signal;
28+
29+
class AudioSettings
30+
{
31+
public:
32+
AudioSettings();
33+
34+
inline qreal duration() const { return m_duration; }
35+
inline int sampleRate() const { return m_sampleRate; }
36+
inline int channelCount() const { return m_channelCount; }
37+
inline int sampleSize() const { return m_sampleSize; }
38+
inline QAudioFormat::SampleType sampleType() const { return m_sampleSize > 8 ? QAudioFormat::SignedInt : QAudioFormat::UnSignedInt; }
39+
inline bool isDirty() const { return m_isDirty; }
40+
41+
inline void setDuration(qreal _duration) { m_duration = _duration; }
42+
void setSampleRate(int _frequency);
43+
void setChannelCount(int _channelCount);
44+
void setSampleSize(int _bitPerSample);
45+
inline void cleanDirty() { m_isDirty = false; }
46+
47+
QJsonObject toJson() const;
48+
void fromJson(const QJsonObject& json, const int version);
49+
50+
private:
51+
qreal m_duration;
52+
int m_sampleRate;
53+
int m_channelCount;
54+
int m_sampleSize;
55+
bool m_isDirty;
56+
};
57+
58+
#endif // AUDIOSETTINGS_H

Exceptions.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2021 Benoit Pelletier
3+
*
4+
* This file is part of Sound Generator.
5+
*
6+
* Sound Generator is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Sound Generator is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with Sound Generator. If not, see <https://www.gnu.org/licenses/>.
18+
*
19+
*/
20+
21+
#ifndef EXCEPTIONS_H
22+
#define EXCEPTIONS_H
23+
24+
#include <QException>
25+
26+
// Used to mark a function as not already implemented, but will be i a future
27+
class NotImplementedException : public QException
28+
{
29+
public:
30+
virtual void raise() const override { throw *this; }
31+
virtual NotImplementedException* clone() const override { return new NotImplementedException(*this); }
32+
virtual const char* what() const override { return "Function is not implemented"; }
33+
};
34+
35+
// Used to announce an error in one of the arguments passed to a function
36+
class ArgumentException : public QException
37+
{
38+
public:
39+
ArgumentException(std::string _message): m_message(_message) {}
40+
ArgumentException(const ArgumentException& _other): m_message(_other.m_message) {}
41+
42+
virtual void raise() const override { throw *this; }
43+
virtual ArgumentException* clone() const override { return new ArgumentException(*this); }
44+
virtual const char* what() const override { return m_message.c_str(); }
45+
private:
46+
std::string m_message;
47+
};
48+
49+
#endif // EXCEPTIONS_H

0 commit comments

Comments
 (0)