Sound generator, a class playing simple notification sounds (1/2 frequency tones).

These tones are generated "in memory", so no sound files ("wav") are needed.

New lib blacksound for utils around audio
This commit is contained in:
Klaus Basan
2014-01-30 13:46:51 +01:00
committed by Mathew Sutcliffe
parent e877c5c368
commit f9225814f9
3 changed files with 178 additions and 76 deletions

View File

@@ -7,26 +7,43 @@
#define BLACKSOUND_SOUNDGENERATOR_H
#include "blackmisc/avselcal.h"
#include "blackmisc/vaudiodevice.h"
#include <QIODevice>
#include <QAudioFormat>
#include <QAudioOutput>
#include <QAudioDeviceInfo>
namespace BlackSound
{
/*!
* \brief Paying simple sounds
*/
class CSoundGenerator : public QIODevice
{
Q_OBJECT
public:
/*!
* \brief How to play
*/
enum PlayMode
{
Single,
SingleWithAutomaticDeletion,
EndlessLoop
};
/*!
* \brief Tone to be played
*/
struct Tone
{
int m_frequencyHz;
int m_secondaryFrequencyHz;
qint64 m_durationMs;
int m_frequencyHz; /*!< first tone's frequency, use 0 for silence */
int m_secondaryFrequencyHz; /*!< second tone's frequency, or 0 */
qint64 m_durationMs; /*!< How long to play */
/*!
* \brief Play frequency f for t milliseconds
@@ -37,41 +54,42 @@ namespace BlackSound
* \brief Play 2 frequencies f for t milliseconds
*/
Tone(int frequencyHz, int secondaryFrequencyHz, qint64 durationMs) : m_frequencyHz(frequencyHz), m_secondaryFrequencyHz(secondaryFrequencyHz), m_durationMs(durationMs) {}
};
/*!
* \brief Constructor
* \param format
* \param device device
* \param format audio format
* \param tones list of Tones
* \param singlePlay play once?
* \param mode play once?
* \param parent
* \see PlayMode
*/
CSoundGenerator(const QAudioFormat &format, const QList<Tone> &tones, bool singlePlay, QObject *parent);
CSoundGenerator(const QAudioDeviceInfo &device, const QAudioFormat &format, const QList<Tone> &tones, PlayMode mode, QObject *parent = nullptr);
/*!
* \brief Constructor
* \param tones list of Tones
* \param singlePlay play once?
* \param mode play once?
* \param parent
* \see PlayMode
*/
CSoundGenerator(const QList<Tone> &tones, bool singlePlay, QObject *parent);
CSoundGenerator(const QList<Tone> &tones, PlayMode mode, QObject *parent = nullptr);
/*!
* Destructor
*/
~CSoundGenerator();
/*!
* \brief Open device
*/
void start();
/*!
* \brief Close device, buffer stays intact
*/
void stop();
void stop(bool destructor = false);
/*!
* \brief sDuration of one cycle
*/
qint64 singleCyleDurationMs() const { return calculateDurationMs(this->m_tones); }
/*!
* \copydoc QIODevice::readData()
@@ -111,6 +129,13 @@ namespace BlackSound
*/
static QAudioFormat defaultAudioFormat();
/*!
* \brief Find the closest Qt device to this audio device
* \param audioDevice output audio device
* \return
*/
static QAudioDeviceInfo findClosestOutputDevice(const BlackMisc::Voice::CAudioDevice &audioDevice);
/*!
* \brief Play signal of tones once
* \param volume 0-100
@@ -128,18 +153,14 @@ namespace BlackSound
*/
static void playSelcal(qint32 volume, const BlackMisc::Aviation::CSelcal &selcal, QAudioDeviceInfo device = QAudioDeviceInfo::defaultOutputDevice());
signals:
/*!
* \brief Device was closed
* \remarks With singleShot the signal indicates that sound sequence has finished
* \brief Play SELCAL tone
* \param volume 0-100
* \param selcal
* \param audioDevice device to be used
* \see BlackMisc::Aviation::CSelcal
*/
void stopped();
private:
/*!
* \brief Generate tone data in internal buffer
*/
void generateData(const QAudioFormat &format, const QList<Tone> &tones);
static void playSelcal(qint32 volume, const BlackMisc::Aviation::CSelcal &selcal, const BlackMisc::Voice::CAudioDevice &audioDevice);
/*!
* \brief One cycle of tones takes t milliseconds
@@ -149,12 +170,36 @@ namespace BlackSound
return this->m_oneCycleDurationMs;
}
signals:
/*!
* \brief Device was closed
* \remarks With singleShot the signal indicates that sound sequence has finished
*/
void stopped();
public slots:
/*!
* \brief Play sound, open device
* \param volume 0..100
*/
void start(int volume);
private:
/*!
* \brief Generate tone data in internal buffer
*/
void generateData();
private:
QList<Tone> m_tones; /*! tones to be played */
qint64 m_position; /*!< position in buffer */
bool m_singlePlay; /*!< end data provisioning after playing all tones */
bool m_playMode; /*!< end data provisioning after playing all tones, play endless loop */
bool m_endReached; /*!< indicates end in combination with single play */
qint64 m_oneCycleDurationMs; /*!< how long is one cycle of tones */
QByteArray m_buffer;
QByteArray m_buffer; /*!< generated buffer for data */
QAudioDeviceInfo m_device; /*!< audio device */
QAudioFormat m_audioFormat; /*!< used format */
QScopedPointer<QAudioOutput> m_audioOutput;
/*!
* \brief Duration of these tones
@@ -163,4 +208,6 @@ namespace BlackSound
};
} //namespace
#endif // guard