Allows to pass two frequencies (as for SELCAL) as tone

This commit is contained in:
Klaus Basan
2014-01-27 01:39:56 +01:00
committed by Mathew Sutcliffe
parent 6d99ddf9b0
commit f71fe743ef
2 changed files with 23 additions and 7 deletions

View File

@@ -63,22 +63,31 @@ namespace BlackSound
while (lengthPerTone) while (lengthPerTone)
{ {
const qreal x = qSin(2 * M_PI * t.m_frequencyHz * qreal(sampleIndexPerTone % format.sampleRate()) / format.sampleRate()); // http://hyperphysics.phy-astr.gsu.edu/hbase/audio/sumdif.html
// http://math.stackexchange.com/questions/164369/how-do-you-calculate-the-frequency-perceived-by-humans-of-two-sinusoidal-waves-a
const double pseudoTime = double(sampleIndexPerTone % format.sampleRate()) / format.sampleRate();
const double amplitude = t.m_secondaryFrequencyHz == 0 ?
qSin(2 * M_PI * t.m_frequencyHz * pseudoTime) :
qSin(M_PI * (t.m_frequencyHz + t.m_secondaryFrequencyHz) * pseudoTime) *
qCos(M_PI * (t.m_frequencyHz - t.m_secondaryFrequencyHz) * pseudoTime);
// the combination of two frequencies actually would have 2*amplitude,
// but I have to normalize with amplitude -1 -> +1
for (int i = 0; i < format.channelCount(); ++i) for (int i = 0; i < format.channelCount(); ++i)
{ {
if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt)
{ {
const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255); const quint8 value = static_cast<quint8>((1.0 + amplitude) / 2 * 255);
*reinterpret_cast<quint8 *>(bufferPointer) = value; *reinterpret_cast<quint8 *>(bufferPointer) = value;
} }
else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt)
{ {
const qint8 value = static_cast<qint8>(x * 127); const qint8 value = static_cast<qint8>(amplitude * 127);
*reinterpret_cast<quint8 *>(bufferPointer) = value; *reinterpret_cast<quint8 *>(bufferPointer) = value;
} }
else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt)
{ {
quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535); quint16 value = static_cast<quint16>((1.0 + amplitude) / 2 * 65535);
if (format.byteOrder() == QAudioFormat::LittleEndian) if (format.byteOrder() == QAudioFormat::LittleEndian)
qToLittleEndian<quint16>(value, bufferPointer); qToLittleEndian<quint16>(value, bufferPointer);
else else
@@ -86,7 +95,7 @@ namespace BlackSound
} }
else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt)
{ {
qint16 value = static_cast<qint16>(x * 32767); qint16 value = static_cast<qint16>(amplitude * 32767);
if (format.byteOrder() == QAudioFormat::LittleEndian) if (format.byteOrder() == QAudioFormat::LittleEndian)
qToLittleEndian<qint16>(value, bufferPointer); qToLittleEndian<qint16>(value, bufferPointer);
else else
@@ -171,7 +180,7 @@ namespace BlackSound
connect(generator, &CSoundGenerator::stopped, audioOutput, &QAudioOutput::stop); connect(generator, &CSoundGenerator::stopped, audioOutput, &QAudioOutput::stop);
connect(generator, &CSoundGenerator::stopped, audioOutput, &QAudioOutput::deleteLater); connect(generator, &CSoundGenerator::stopped, audioOutput, &QAudioOutput::deleteLater);
qreal vol = volume / 100.0; double vol = volume / 100.0;
audioOutput->setVolume(vol); audioOutput->setVolume(vol);
generator->start(); generator->start();
audioOutput->start(generator); audioOutput->start(generator);

View File

@@ -24,12 +24,19 @@ namespace BlackSound
struct Tone struct Tone
{ {
int m_frequencyHz; int m_frequencyHz;
int m_secondaryFrequencyHz;
qint64 m_durationMs; qint64 m_durationMs;
/*! /*!
* \brief Play frequency f for t milliseconds * \brief Play frequency f for t milliseconds
*/ */
Tone(int frequencyHz, qint64 durationMs) : m_frequencyHz(frequencyHz), m_durationMs(durationMs) {} Tone(int frequencyHz, qint64 durationMs) : m_frequencyHz(frequencyHz), m_secondaryFrequencyHz(0), m_durationMs(durationMs) {}
/*!
* \brief Play 2 frequencies f for t milliseconds
*/
Tone(int frequencyHz, int secondaryFrequencyHz, qint64 durationMs) : m_frequencyHz(frequencyHz), m_secondaryFrequencyHz(secondaryFrequencyHz), m_durationMs(durationMs) {}
}; };
/*! /*!