WSJT-X/soundin.cpp
Joe Taylor 61f023ddd1 Most of these changes are thanks to G4WJS. Audio I/O is now done using
Qt's built-in QAudio calls rather than PortAudio.  Also includes some
refactoring of the arrangement for these calls, and more use of C++ style.


git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3523 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
2013-08-05 13:57:55 +00:00

128 lines
2.8 KiB
C++

#include "soundin.h"
#include <QAudioDeviceInfo>
#include <QAudioFormat>
#include <QAudioInput>
#include <QDebug>
bool SoundInput::audioError () const
{
bool result (true);
Q_ASSERT_X (m_stream, "SoundInput", "programming error");
if (m_stream)
{
switch (m_stream->error ())
{
case QAudio::OpenError:
Q_EMIT error (tr ("An error opening the audio input device has occurred."));
break;
case QAudio::IOError:
Q_EMIT error (tr ("An error occurred during read from the audio input device."));
break;
case QAudio::UnderrunError:
Q_EMIT error (tr ("Audio data not being fed to the audio input device fast enough."));
break;
case QAudio::FatalError:
Q_EMIT error (tr ("Non-recoverable error, audio input device not usable at this time."));
break;
case QAudio::NoError:
result = false;
break;
}
}
return result;
}
bool SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, QIODevice * sink)
{
stop();
QAudioFormat format (device.preferredFormat());
format.setChannelCount (1);
format.setCodec ("audio/pcm");
format.setSampleRate (12000);
format.setSampleType (QAudioFormat::SignedInt);
format.setSampleSize (16);
if (!format.isValid ())
{
Q_EMIT error (tr ("Requested input audio format is not valid."));
return false;
}
// this function lies!
// if (!device.isFormatSupported (format))
// {
// Q_EMIT error (tr ("Requested input audio format is not supported on device."));
// return false;
// }
m_stream.reset (new QAudioInput (device, format, this));
if (audioError ())
{
return false;
}
connect (m_stream.data(), &QAudioInput::stateChanged, this, &SoundInput::handleStateChanged);
m_stream->setBufferSize (m_stream->format ().bytesForFrames (framesPerBuffer));
m_stream->start (sink);
qDebug () << "audio input buffer size = " << m_stream->bufferSize () << " bytes\n";
return audioError () ? false : true;
}
void SoundInput::handleStateChanged (QAudio::State newState) const
{
switch (newState)
{
case QAudio::IdleState:
qDebug () << "SoundInput idle\n";
Q_EMIT status (tr ("Idle"));
break;
case QAudio::ActiveState:
qDebug () << "SoundInput active\n";
Q_EMIT status (tr ("Receiving"));
break;
case QAudio::SuspendedState:
qDebug () << "SoundInput suspended\n";
Q_EMIT status (tr ("Suspended"));
break;
case QAudio::StoppedState:
if (audioError ())
{
qDebug () << "SoundInput error\n";
Q_EMIT status (tr ("Error"));
}
else
{
qDebug () << "SoundInput stopped\n";
Q_EMIT status (tr ("Stopped"));
}
break;
}
}
void SoundInput::stop()
{
if (m_stream)
{
m_stream->stop ();
}
m_stream.reset ();
}
SoundInput::~SoundInput ()
{
}