mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-09-12 08:16:39 -04:00
Windows Vista has a broken rate converter which gets invoked when an input audio stream at 48kHz sampel rate is requested. I've no idea why our application can't get exclusive access to the audio input device and have a unconverted stream direct at 48kHz. To get around this our down sampling filter for audio input from 48kHz to 12kHz is disaabled by default on Windows Vista, instead we request a 12kHz stream and process it directly. This default behviour can be overriden by specifying the following settings value: [Tune] Audio\DisableInputResampling=false This settings value defaults to true on Windows Vista and false everywhere else so normally needn't be present. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3588 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
121 lines
2.6 KiB
C++
121 lines
2.6 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;
|
|
}
|
|
|
|
void SoundInput::start(QAudioDeviceInfo const& device, unsigned channels, int framesPerBuffer, QIODevice * sink, unsigned downSampleFactor)
|
|
{
|
|
Q_ASSERT (0 < channels && channels < 3);
|
|
Q_ASSERT (sink);
|
|
|
|
stop();
|
|
|
|
QAudioFormat format (device.preferredFormat());
|
|
format.setChannelCount (channels);
|
|
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, this));
|
|
if (audioError ())
|
|
{
|
|
return;
|
|
}
|
|
|
|
connect (m_stream.data(), &QAudioInput::stateChanged, this, &SoundInput::handleStateChanged);
|
|
m_stream->setBufferSize (m_stream->format ().bytesForFrames (framesPerBuffer));
|
|
m_stream->start (sink);
|
|
audioError ();
|
|
}
|
|
|
|
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 ();
|
|
}
|
|
|
|
SoundInput::~SoundInput ()
|
|
{
|
|
}
|