mirror of https://github.com/f4exb/sdrangel.git
Audio output: forward actual sample rate to Audio Manager
This commit is contained in:
parent
768d3f1398
commit
5df7f73da7
|
@ -96,6 +96,8 @@ AudioDeviceManager::AudioDeviceManager()
|
||||||
|
|
||||||
m_defaultInputStarted = false;
|
m_defaultInputStarted = false;
|
||||||
m_defaultOutputStarted = false;
|
m_defaultOutputStarted = false;
|
||||||
|
|
||||||
|
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDeviceManager::~AudioDeviceManager()
|
AudioDeviceManager::~AudioDeviceManager()
|
||||||
|
@ -281,6 +283,7 @@ void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, MessageQueue *sample
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("AudioDeviceManager::addAudioSink: new AudioOutputDevice on thread: %p", thread);
|
qDebug("AudioDeviceManager::addAudioSink: new AudioOutputDevice on thread: %p", thread);
|
||||||
|
audioOutputDevice->setManagerMessageQueue(&m_inputMessageQueue);
|
||||||
audioOutputDevice->moveToThread(thread);
|
audioOutputDevice->moveToThread(thread);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
|
@ -445,7 +448,6 @@ void AudioDeviceManager::startAudioOutput(int outputDeviceIndex)
|
||||||
AudioOutputDevice::MsgStart *msg = AudioOutputDevice::MsgStart::create(outputDeviceIndex, sampleRate);
|
AudioOutputDevice::MsgStart *msg = AudioOutputDevice::MsgStart::create(outputDeviceIndex, sampleRate);
|
||||||
m_audioOutputs[outputDeviceIndex]->getInputMessageQueue()->push(msg);
|
m_audioOutputs[outputDeviceIndex]->getInputMessageQueue()->push(msg);
|
||||||
|
|
||||||
m_audioOutputInfos[deviceName].sampleRate = sampleRate; // FIXME: possible change of sample rate in AudioOutputDevice
|
|
||||||
m_audioOutputInfos[deviceName].udpAddress = udpAddress;
|
m_audioOutputInfos[deviceName].udpAddress = udpAddress;
|
||||||
m_audioOutputInfos[deviceName].udpPort = udpPort;
|
m_audioOutputInfos[deviceName].udpPort = udpPort;
|
||||||
m_audioOutputInfos[deviceName].copyToUDP = copyAudioToUDP;
|
m_audioOutputInfos[deviceName].copyToUDP = copyAudioToUDP;
|
||||||
|
@ -488,7 +490,7 @@ void AudioDeviceManager::startAudioInput(int inputDeviceIndex)
|
||||||
|
|
||||||
m_audioInputs[inputDeviceIndex]->start(inputDeviceIndex, sampleRate);
|
m_audioInputs[inputDeviceIndex]->start(inputDeviceIndex, sampleRate);
|
||||||
m_audioInputs[inputDeviceIndex]->setVolume(volume);
|
m_audioInputs[inputDeviceIndex]->setVolume(volume);
|
||||||
m_audioInputInfos[deviceName].sampleRate = m_audioInputs[inputDeviceIndex]->getRate();
|
m_audioInputInfos[deviceName].sampleRate = m_audioInputs[inputDeviceIndex]->getRate(); // FIXME
|
||||||
m_audioInputInfos[deviceName].volume = volume;
|
m_audioInputInfos[deviceName].volume = volume;
|
||||||
m_defaultInputStarted = (inputDeviceIndex == -1);
|
m_defaultInputStarted = (inputDeviceIndex == -1);
|
||||||
}
|
}
|
||||||
|
@ -671,17 +673,6 @@ void AudioDeviceManager::setOutputDeviceInfo(int outputDeviceIndex, const Output
|
||||||
|
|
||||||
AudioOutputDevice::MsgStart *msgStart = AudioOutputDevice::MsgStart::create(outputDeviceIndex, deviceInfo.sampleRate);
|
AudioOutputDevice::MsgStart *msgStart = AudioOutputDevice::MsgStart::create(outputDeviceIndex, deviceInfo.sampleRate);
|
||||||
audioOutput->getInputMessageQueue()->push(msgStart);
|
audioOutput->getInputMessageQueue()->push(msgStart);
|
||||||
|
|
||||||
m_audioOutputInfos[deviceName].sampleRate = audioOutput->getRate(); // store actual sample rate
|
|
||||||
|
|
||||||
// send message to attached channels
|
|
||||||
QList<MessageQueue *>::const_iterator it = m_outputDeviceSinkMessageQueues[outputDeviceIndex].begin();
|
|
||||||
|
|
||||||
for (; it != m_outputDeviceSinkMessageQueues[outputDeviceIndex].end(); ++it)
|
|
||||||
{
|
|
||||||
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioOutputInfos[deviceName].sampleRate, DSPConfigureAudio::AudioOutput);
|
|
||||||
(*it)->push(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
audioOutput->setUdpCopyToUDP(deviceInfo.copyToUDP);
|
audioOutput->setUdpCopyToUDP(deviceInfo.copyToUDP);
|
||||||
|
@ -724,18 +715,6 @@ void AudioDeviceManager::unsetOutputDeviceInfo(int outputDeviceIndex)
|
||||||
|
|
||||||
stopAudioOutput(outputDeviceIndex);
|
stopAudioOutput(outputDeviceIndex);
|
||||||
startAudioOutput(outputDeviceIndex);
|
startAudioOutput(outputDeviceIndex);
|
||||||
|
|
||||||
if (oldDeviceInfo.sampleRate != m_audioOutputInfos[deviceName].sampleRate)
|
|
||||||
{
|
|
||||||
// send message to attached channels
|
|
||||||
QList<MessageQueue *>::const_iterator it = m_outputDeviceSinkMessageQueues[outputDeviceIndex].begin();
|
|
||||||
|
|
||||||
for (; it != m_outputDeviceSinkMessageQueues[outputDeviceIndex].end(); ++it)
|
|
||||||
{
|
|
||||||
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioOutputInfos[deviceName].sampleRate, DSPConfigureAudio::AudioOutput);
|
|
||||||
(*it)->push(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceManager::unsetInputDeviceInfo(int inputDeviceIndex)
|
void AudioDeviceManager::unsetInputDeviceInfo(int inputDeviceIndex)
|
||||||
|
@ -865,3 +844,40 @@ void AudioDeviceManager::debugAudioOutputInfos() const
|
||||||
<< " decimationFactor: " << it.value().udpDecimationFactor;
|
<< " decimationFactor: " << it.value().udpDecimationFactor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioDeviceManager::handleMessage(const Message& msg)
|
||||||
|
{
|
||||||
|
if (AudioOutputDevice::MsgReportSampleRate::match(msg))
|
||||||
|
{
|
||||||
|
AudioOutputDevice::MsgReportSampleRate& report = (AudioOutputDevice::MsgReportSampleRate&) msg;
|
||||||
|
int deviceIndex = report.getDeviceIndex();
|
||||||
|
const QString& deviceName = report.getDeviceName();
|
||||||
|
int sampleRate = report.getSampleRate();
|
||||||
|
qDebug("AudioDeviceManager::handleMessage: AudioOutputDevice::MsgReportSampleRate: device(%d) %s: rate: %d",
|
||||||
|
deviceIndex, qPrintable(deviceName), sampleRate);
|
||||||
|
m_audioOutputInfos[deviceName].sampleRate = sampleRate;
|
||||||
|
|
||||||
|
// send message to attached channels
|
||||||
|
for (auto& messageQueue : m_outputDeviceSinkMessageQueues[deviceIndex])
|
||||||
|
{
|
||||||
|
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioOutputInfos[deviceName].sampleRate, DSPConfigureAudio::AudioOutput);
|
||||||
|
messageQueue->push(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDeviceManager::handleInputMessages()
|
||||||
|
{
|
||||||
|
Message* message;
|
||||||
|
|
||||||
|
while ((message = m_inputMessageQueue.pop()) != nullptr)
|
||||||
|
{
|
||||||
|
if (handleMessage(*message)) {
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,18 +22,20 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include "audio/audioinputdevice.h"
|
#include "audio/audioinputdevice.h"
|
||||||
#include "audio/audiooutputdevice.h"
|
#include "audio/audiooutputdevice.h"
|
||||||
#include "audio/audiodeviceinfo.h"
|
#include "audio/audiodeviceinfo.h"
|
||||||
|
#include "util/messagequeue.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
|
||||||
class QThread;
|
class QThread;
|
||||||
class QDataStream;
|
class QDataStream;
|
||||||
class AudioFifo;
|
class AudioFifo;
|
||||||
class MessageQueue;
|
|
||||||
|
|
||||||
class SDRBASE_API AudioDeviceManager {
|
class SDRBASE_API AudioDeviceManager : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
class InputDeviceInfo
|
class InputDeviceInfo
|
||||||
{
|
{
|
||||||
|
@ -149,6 +151,8 @@ private:
|
||||||
bool m_defaultOutputStarted; //!< True if the default audio output (-1) has already been started
|
bool m_defaultOutputStarted; //!< True if the default audio output (-1) has already been started
|
||||||
bool m_defaultInputStarted; //!< True if the default audio input (-1) has already been started
|
bool m_defaultInputStarted; //!< True if the default audio input (-1) has already been started
|
||||||
|
|
||||||
|
MessageQueue m_inputMessageQueue;
|
||||||
|
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
bool deserialize(const QByteArray& data);
|
bool deserialize(const QByteArray& data);
|
||||||
|
@ -166,7 +170,12 @@ private:
|
||||||
void deserializeOutputMap(QByteArray& data);
|
void deserializeOutputMap(QByteArray& data);
|
||||||
void debugAudioOutputInfos() const;
|
void debugAudioOutputInfos() const;
|
||||||
|
|
||||||
|
bool handleMessage(const Message& cmd);
|
||||||
|
|
||||||
friend class MainSettings;
|
friend class MainSettings;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleInputMessages();
|
||||||
};
|
};
|
||||||
|
|
||||||
QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::InputDeviceInfo& info);
|
QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::InputDeviceInfo& info);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
MESSAGE_CLASS_DEFINITION(AudioOutputDevice::MsgStart, Message)
|
MESSAGE_CLASS_DEFINITION(AudioOutputDevice::MsgStart, Message)
|
||||||
MESSAGE_CLASS_DEFINITION(AudioOutputDevice::MsgStop, Message)
|
MESSAGE_CLASS_DEFINITION(AudioOutputDevice::MsgStop, Message)
|
||||||
|
MESSAGE_CLASS_DEFINITION(AudioOutputDevice::MsgReportSampleRate, Message)
|
||||||
|
|
||||||
AudioOutputDevice::AudioOutputDevice() :
|
AudioOutputDevice::AudioOutputDevice() :
|
||||||
m_audioOutput(nullptr),
|
m_audioOutput(nullptr),
|
||||||
|
@ -47,7 +48,8 @@ AudioOutputDevice::AudioOutputDevice() :
|
||||||
m_recordSilenceTime(0),
|
m_recordSilenceTime(0),
|
||||||
m_recordSilenceNbSamples(0),
|
m_recordSilenceNbSamples(0),
|
||||||
m_recordSilenceCount(0),
|
m_recordSilenceCount(0),
|
||||||
m_audioFifos()
|
m_audioFifos(),
|
||||||
|
m_managerMessageQueue(nullptr)
|
||||||
{
|
{
|
||||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
@ -66,18 +68,18 @@ AudioOutputDevice::~AudioOutputDevice()
|
||||||
// m_audioFifos.clear();
|
// m_audioFifos.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioOutputDevice::start(int device, int rate)
|
bool AudioOutputDevice::start(int deviceIndex, int sampleRate)
|
||||||
{
|
{
|
||||||
// if (m_audioOutput) {
|
// if (m_audioOutput) {
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// if (m_audioUsageCount == 0)
|
// if (m_audioUsageCount == 0)
|
||||||
// {
|
// {
|
||||||
qDebug("AudioOutputDevice::start: device: %d rate: %d thread: %p", device, rate, QThread::currentThread());
|
qDebug("AudioOutputDevice::start: device: %d rate: %d thread: %p", deviceIndex, sampleRate, QThread::currentThread());
|
||||||
QMutexLocker mutexLocker(&m_mutex);
|
QMutexLocker mutexLocker(&m_mutex);
|
||||||
AudioDeviceInfo devInfo;
|
AudioDeviceInfo devInfo;
|
||||||
|
|
||||||
if (device < 0)
|
if (deviceIndex < 0)
|
||||||
{
|
{
|
||||||
devInfo = AudioDeviceInfo::defaultOutputDevice();
|
devInfo = AudioDeviceInfo::defaultOutputDevice();
|
||||||
qWarning("AudioOutputDevice::start: using system default device %s", qPrintable(devInfo.defaultOutputDevice().deviceName()));
|
qWarning("AudioOutputDevice::start: using system default device %s", qPrintable(devInfo.defaultOutputDevice().deviceName()));
|
||||||
|
@ -86,15 +88,16 @@ bool AudioOutputDevice::start(int device, int rate)
|
||||||
{
|
{
|
||||||
QList<AudioDeviceInfo> devicesInfo = AudioDeviceInfo::availableOutputDevices();
|
QList<AudioDeviceInfo> devicesInfo = AudioDeviceInfo::availableOutputDevices();
|
||||||
|
|
||||||
if (device < devicesInfo.size())
|
if (deviceIndex < devicesInfo.size())
|
||||||
{
|
{
|
||||||
devInfo = devicesInfo[device];
|
devInfo = devicesInfo[deviceIndex];
|
||||||
qWarning("AudioOutputDevice::start: using audio device #%d: %s", device, qPrintable(devInfo.deviceName()));
|
qWarning("AudioOutputDevice::start: using audio device #%d: %s", deviceIndex, qPrintable(devInfo.deviceName()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
devInfo = AudioDeviceInfo::defaultOutputDevice();
|
devInfo = AudioDeviceInfo::defaultOutputDevice();
|
||||||
qWarning("AudioOutputDevice::start: audio device #%d does not exist. Using system default device %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName()));
|
qWarning("AudioOutputDevice::start: audio device #%d does not exist. Using system default device %s", deviceIndex, qPrintable(devInfo.defaultOutputDevice().deviceName()));
|
||||||
|
deviceIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +107,7 @@ bool AudioOutputDevice::start(int device, int rate)
|
||||||
m_audioFormat = devInfo.deviceInfo().preferredFormat();
|
m_audioFormat = devInfo.deviceInfo().preferredFormat();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_audioFormat.setSampleRate(rate);
|
m_audioFormat.setSampleRate(sampleRate);
|
||||||
m_audioFormat.setChannelCount(2);
|
m_audioFormat.setChannelCount(2);
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
m_audioFormat.setSampleFormat(QAudioFormat::Int16);
|
m_audioFormat.setSampleFormat(QAudioFormat::Int16);
|
||||||
|
@ -118,7 +121,7 @@ bool AudioOutputDevice::start(int device, int rate)
|
||||||
if (!devInfo.isFormatSupported(m_audioFormat))
|
if (!devInfo.isFormatSupported(m_audioFormat))
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
qWarning("AudioOutputDevice::start: format %d Hz 2xS16LE audio/pcm not supported.", rate);
|
qWarning("AudioOutputDevice::start: format %d Hz 2xS16LE audio/pcm not supported.", sampleRate);
|
||||||
#else
|
#else
|
||||||
m_audioFormat = devInfo.deviceInfo().nearestFormat(m_audioFormat);
|
m_audioFormat = devInfo.deviceInfo().nearestFormat(m_audioFormat);
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
@ -128,7 +131,7 @@ bool AudioOutputDevice::start(int device, int rate)
|
||||||
<< " codec: " << m_audioFormat.codec().toStdString()
|
<< " codec: " << m_audioFormat.codec().toStdString()
|
||||||
<< " byteOrder: " << (m_audioFormat.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE")
|
<< " byteOrder: " << (m_audioFormat.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE")
|
||||||
<< " sampleType: " << (int) m_audioFormat.sampleType();
|
<< " sampleType: " << (int) m_audioFormat.sampleType();
|
||||||
qWarning("AudioOutputDevice::start: format %d Hz 2xS16LE audio/pcm not supported. Using: %s", rate, os.str().c_str());
|
qWarning("AudioOutputDevice::start: format %d Hz 2xS16LE audio/pcm not supported. Using: %s", sampleRate, os.str().c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -161,7 +164,7 @@ bool AudioOutputDevice::start(int device, int rate)
|
||||||
// m_audioOutput->setBufferSize(m_audioFormat.sampleRate() / 5); FIXME: does not work generally
|
// m_audioOutput->setBufferSize(m_audioFormat.sampleRate() / 5); FIXME: does not work generally
|
||||||
m_recordSilenceNbSamples = (m_recordSilenceTime * m_audioFormat.sampleRate()) / 10; // time in 100'ś ms
|
m_recordSilenceNbSamples = (m_recordSilenceTime * m_audioFormat.sampleRate()) / 10; // time in 100'ś ms
|
||||||
|
|
||||||
QIODevice::open(QIODevice::ReadOnly);
|
QIODevice::open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||||
|
|
||||||
m_audioOutput->start(this);
|
m_audioOutput->start(this);
|
||||||
|
|
||||||
|
@ -170,6 +173,10 @@ bool AudioOutputDevice::start(int device, int rate)
|
||||||
} else {
|
} else {
|
||||||
qDebug("AudioOutputDevice::start: started buffer: %d bytes", m_audioOutput->bufferSize());
|
qDebug("AudioOutputDevice::start: started buffer: %d bytes", m_audioOutput->bufferSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_managerMessageQueue) {
|
||||||
|
m_managerMessageQueue->push(AudioOutputDevice::MsgReportSampleRate::create(deviceIndex, devInfo.deviceName(), m_audioFormat.sampleRate()));
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// m_audioUsageCount++;
|
// m_audioUsageCount++;
|
||||||
|
|
|
@ -77,6 +77,30 @@ public:
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MsgReportSampleRate : public Message {
|
||||||
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
public:
|
||||||
|
int getDeviceIndex() const { return m_deviceIndex; }
|
||||||
|
const QString& getDeviceName() const { return m_deviceName; }
|
||||||
|
int getSampleRate() const { return m_sampleRate; }
|
||||||
|
|
||||||
|
static MsgReportSampleRate* create(int deviceIndex, const QString& deviceName, int sampleRate) {
|
||||||
|
return new MsgReportSampleRate(deviceIndex, deviceName, sampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_deviceIndex;
|
||||||
|
QString m_deviceName;
|
||||||
|
int m_sampleRate;
|
||||||
|
|
||||||
|
MsgReportSampleRate(int deviceIndex, const QString& deviceName, int sampleRate) :
|
||||||
|
Message(),
|
||||||
|
m_deviceIndex(deviceIndex),
|
||||||
|
m_deviceName(deviceName),
|
||||||
|
m_sampleRate(sampleRate)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
enum UDPChannelMode
|
enum UDPChannelMode
|
||||||
{
|
{
|
||||||
UDPChannelLeft,
|
UDPChannelLeft,
|
||||||
|
@ -118,6 +142,7 @@ public:
|
||||||
void setDeviceName(const QString& deviceName) { m_deviceName = deviceName;}
|
void setDeviceName(const QString& deviceName) { m_deviceName = deviceName;}
|
||||||
|
|
||||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||||
|
void setManagerMessageQueue(MessageQueue *messageQueue) { m_managerMessageQueue = messageQueue; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QRecursiveMutex m_mutex;
|
QRecursiveMutex m_mutex;
|
||||||
|
@ -147,6 +172,7 @@ private:
|
||||||
QString m_deviceName;
|
QString m_deviceName;
|
||||||
|
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
|
MessageQueue *m_managerMessageQueue;
|
||||||
|
|
||||||
//virtual bool open(OpenMode mode);
|
//virtual bool open(OpenMode mode);
|
||||||
virtual qint64 readData(char* data, qint64 maxLen);
|
virtual qint64 readData(char* data, qint64 maxLen);
|
||||||
|
@ -155,7 +181,7 @@ private:
|
||||||
void writeSampleToFile(qint16 lSample, qint16 rSample);
|
void writeSampleToFile(qint16 lSample, qint16 rSample);
|
||||||
bool handleMessage(const Message& cmd);
|
bool handleMessage(const Message& cmd);
|
||||||
|
|
||||||
bool start(int device, int rate);
|
bool start(int deviceIndex, int sampleRate);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
friend class AudioOutputPipe;
|
friend class AudioOutputPipe;
|
||||||
|
|
Loading…
Reference in New Issue