WSJT-X/soundin.cpp
Bill Somerville 581691befb Rearranged sequencing of audio streams and devices.
The code  was starting streams linked  to closed devices which  may be
causing issues on  the Mac version.  I have refactored  to ensure that
devices are always opened before related audio streams are started.

Made .h C++ headers emacs friendly.

Removed some code in the MainWindow  contructor that read the log file
but failed to check if the file exists and didn't do anything with the
data anyway.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3977 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
2014-04-03 19:29:13 +00:00

138 lines
3.0 KiB
C++

#include "soundin.h"
#include <QAudioDeviceInfo>
#include <QAudioFormat>
#include <QAudioInput>
#include <QDebug>
#include "moc_soundin.cpp"
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;
}
void SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, AudioDevice * sink, unsigned downSampleFactor, AudioDevice::Channel channel)
{
Q_ASSERT (sink);
stop ();
m_sink = sink;
QAudioFormat format (device.preferredFormat());
format.setChannelCount (AudioDevice::Mono == channel ? 1 : 2);
format.setCodec ("audio/pcm");
format.setSampleRate (12000 * downSampleFactor);
format.setSampleType (QAudioFormat::SignedInt);
format.setSampleSize (16);
if (!format.isValid ())
{
Q_EMIT error (tr ("Requested input audio format is not valid."));
return;
}
// this function lies!
// if (!device.isFormatSupported (format))
// {
// Q_EMIT error (tr ("Requested input audio format is not supported on device."));
// return;
// }
m_stream.reset (new QAudioInput {device, format});
if (audioError ())
{
return;
}
connect (m_stream.data(), &QAudioInput::stateChanged, this, &SoundInput::handleStateChanged);
m_stream->setBufferSize (m_stream->format ().bytesForFrames (framesPerBuffer));
if (sink->initialize (QIODevice::WriteOnly, channel))
{
m_stream->start (sink);
audioError ();
}
else
{
Q_EMIT error (tr ("Failed to initialize audio sink device"));
}
}
void SoundInput::handleStateChanged (QAudio::State newState) const
{
switch (newState)
{
case QAudio::IdleState:
Q_EMIT status (tr ("Idle"));
break;
case QAudio::ActiveState:
Q_EMIT status (tr ("Receiving"));
break;
case QAudio::SuspendedState:
Q_EMIT status (tr ("Suspended"));
break;
case QAudio::StoppedState:
if (audioError ())
{
Q_EMIT status (tr ("Error"));
}
else
{
Q_EMIT status (tr ("Stopped"));
}
break;
}
}
void SoundInput::stop()
{
if (m_stream)
{
m_stream->stop ();
}
m_stream.reset ();
if (m_sink)
{
m_sink->close ();
}
}
SoundInput::~SoundInput ()
{
stop ();
}