diff options
Diffstat (limited to 'src/plugins/Output/qtmultimedia/outputqtmultimedia.cpp')
| -rw-r--r-- | src/plugins/Output/qtmultimedia/outputqtmultimedia.cpp | 184 |
1 files changed, 98 insertions, 86 deletions
diff --git a/src/plugins/Output/qtmultimedia/outputqtmultimedia.cpp b/src/plugins/Output/qtmultimedia/outputqtmultimedia.cpp index 1f39ecc60..7de68b081 100644 --- a/src/plugins/Output/qtmultimedia/outputqtmultimedia.cpp +++ b/src/plugins/Output/qtmultimedia/outputqtmultimedia.cpp @@ -19,7 +19,8 @@ ***************************************************************************/ #include "outputqtmultimedia.h" - +#include <qmmp/audioparameters.h> +#include <QMetaObject> #include <QAudioOutput> #include <QAudioFormat> #include <QAudioDeviceInfo> @@ -38,114 +39,125 @@ OutputQtMultimedia::~OutputQtMultimedia() bool OutputQtMultimedia::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format) { - QAudioFormat qformat; - qformat.setCodec("audio/pcm"); - qformat.setFrequency(freq); - qformat.setByteOrder(QAudioFormat::LittleEndian); - qformat.setChannels(map.size()); - qformat.setSampleType(QAudioFormat::SignedInt); - - //Size of sample representation in input data. For 24-bit is 4, high byte is ignored. - qint64 bytes_per_sample = 0; - - switch (format) - { - case Qmmp::PCM_S8: - qformat.setSampleSize(8); - bytes_per_sample = 1; - break; - case Qmmp::PCM_S16LE: - qformat.setSampleSize(16); - bytes_per_sample = 2; - break; - case Qmmp::PCM_S24LE: - qformat.setSampleSize(24); - bytes_per_sample = 4; - break; - case Qmmp::PCM_S32LE: - qformat.setSampleSize(32); - bytes_per_sample = 4; - break; - default: - break; - } - - if (!qformat.isValid()) - return false; - - m_bytes_per_second = bytes_per_sample * freq * qformat.channels(); - - const QSettings settings(Qmmp::configFile(), QSettings::IniFormat); - const QString saved_device_name = settings.value("QTMULTIMEDIA/device").toString(); - - QAudioDeviceInfo device_info; - if (!saved_device_name.isEmpty()) - { - const QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); - foreach (const QAudioDeviceInfo &info, devices) - { - if (info.deviceName()==saved_device_name) - { - if (info.isFormatSupported(qformat)) - { - device_info = info; - break; - } - else - qDebug() << "OutputQtMultimedia: Output device: " << saved_device_name << " is not supported"; - } - } - } - - if (device_info.isNull()) - { - device_info = QAudioDeviceInfo::defaultOutputDevice(); - if (!device_info.isFormatSupported(qformat)) - return false; - } - - qDebug() << "OutputQtMultimedia: Using output device: " << device_info.deviceName(); - - m_output.reset(new QAudioOutput(device_info, qformat)); - m_buffer = m_output->start(); - - configure(freq, map, format); - return true; + QAudioFormat qformat; + qformat.setCodec("audio/pcm"); + qformat.setSampleRate(freq); + qformat.setByteOrder(QAudioFormat::LittleEndian); + qformat.setChannelCount(map.size()); + qformat.setSampleType(QAudioFormat::SignedInt); + + //Size of sample representation in input data. For 24-bit is 4, high byte is ignored. + qint64 bytes_per_sample = AudioParameters::sampleSize(format); + + switch (format) + { + case Qmmp::PCM_S8: + qformat.setSampleSize(8); + break; + case Qmmp::PCM_S16LE: + qformat.setSampleSize(16); + break; + case Qmmp::PCM_S24LE: + qformat.setSampleSize(24); + break; + case Qmmp::PCM_S32LE: + qformat.setSampleSize(32); + break; + default: + break; + } + + if (!qformat.isValid()) + return false; + + const QSettings settings(Qmmp::configFile(), QSettings::IniFormat); + const QString saved_device_name = settings.value("QTMULTIMEDIA/device").toString(); + + m_bytes_per_second = bytes_per_sample * freq * qformat.channelCount(); + + QAudioDeviceInfo device_info; + if (!saved_device_name.isEmpty()) + { + const QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + foreach (const QAudioDeviceInfo &info, devices) + { + if (info.deviceName()==saved_device_name) + { + if (info.isFormatSupported(qformat)) + { + device_info = info; + break; + } + else + qDebug() << "OutputQtMultimedia: Output device: " << saved_device_name << " is not supported"; + } + } + } + + if (device_info.isNull()) + { + device_info = QAudioDeviceInfo::defaultOutputDevice(); + if (!device_info.isFormatSupported(qformat)) + return false; + } + + qDebug() << "OutputQtMultimedia: Using output device: " << device_info.deviceName(); + + m_output.reset(new QAudioOutput(device_info, qformat)); + m_buffer = m_output->start(); + m_control.reset(new OutputControl(m_output.data())); + + configure(freq, map, format); + return true; } qint64 OutputQtMultimedia::latency() { - return 0; + return 0; } qint64 OutputQtMultimedia::writeAudio(unsigned char *data, qint64 maxSize) { - if (!m_output->bytesFree()) { - //If the buffer is full, waiting for some bytes to be played: - //trying to play maxSize bytes, but not more than half of buffer. - usleep(qMin(maxSize, static_cast<qint64>(m_output->bufferSize() / 2)) * 1000000 / m_bytes_per_second); - } - return m_buffer->write((const char*)data, maxSize); + if (!m_output->bytesFree()) { + //If the buffer is full, waiting for some bytes to be played: + //trying to play maxSize bytes, but not more than half of buffer. + usleep(qMin(maxSize, static_cast<qint64>(m_output->bufferSize() / 2)) * 1000000 / m_bytes_per_second); + } + return m_buffer->write((const char*)data, maxSize); } void OutputQtMultimedia::drain() { - m_buffer->waitForBytesWritten(-1); + m_buffer->waitForBytesWritten(-1); } void OutputQtMultimedia::reset() { - m_buffer->reset(); - m_buffer = m_output->start(); + m_buffer->reset(); } void OutputQtMultimedia::suspend() { - m_output->suspend(); + QMetaObject::invokeMethod(m_control.data(), "suspend", Qt::QueuedConnection); } void OutputQtMultimedia::resume() { - m_output->resume(); + QMetaObject::invokeMethod(m_control.data(), "resume", Qt::QueuedConnection); +} + +OutputControl::OutputControl(QAudioOutput *o) +{ + m_output = o; +} + +void OutputControl::suspend() +{ + m_output->suspend(); +} + +void OutputControl::resume() +{ + m_output->resume(); } |
