以下是在QT5中编写的读取音频输入(麦克风)并将其放入64K循环缓冲区的代码。一旦缓冲区有数据,它就会将其写入音频输出(PC上的扬声器)。这是一个非常基础的代码,可以作为熟悉音频设备的起点。注意,此处音频输入和输出在一个对象中,可能会导致缓冲区问题。要解决这个问题,需要创建单独的输入和输出对象。
程序分为两个文件,第一个是qt配置文件(.pro),第二个是main.cpp文件。
#AudioEcho.pro file for QT5.2.1
QT += core
QT -= gui
QT += multimedia widgets
TARGET = AudioEcho
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
#include <QDebug>
#include <QIODevice>
#include <QAudioInput>
#include <QAudioOutput>
#include <QCoreApplication>
class myAudio :public QIODevice
{
public:
QAudioOutput *audioOut;
QAudioInput *audioIn;
myAudio();
~myAudio(){}
void fillBuffer();
QAudioFormat formatIn,formatOut;
QByteArray buff;
char *pbuff;
quint64 RXbuff;
quint64 buffPtr;
protected:
qint64 readData(char *data, qint64 maxlen);
qint64 writeData(const char *data, qint64 len);
qint64 bytesAvailable() const;
};
#define SAMPLE_RATE 22050
#define CHANNELS 1
#define SAMPLE_SIZE 16
#define SAMPLE_TYPE SignedInt
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
myAudio *m= new myAudio();
return a.exec();
}
myAudio::myAudio()
{
formatIn.setSampleRate(SAMPLE_RATE);
formatIn.setChannelCount(CHANNELS);
formatIn.setSampleSize(SAMPLE_SIZE);
formatIn.setCodec("audio/pcm");
formatIn.setByteOrder(QAudioFormat::LittleEndian);
formatIn.setSampleType(QAudioFormat::SAMPLE_TYPE);
formatOut.setSampleRate(SAMPLE_RATE);
formatOut.setChannelCount(CHANNELS);
formatOut.setSampleSize(SAMPLE_SIZE);
formatOut.setCodec("audio/pcm");
formatOut.setByteOrder(QAudioFormat::LittleEndian);
formatOut.setSampleType(QAudioFormat::SAMPLE_TYPE);
QAudioDeviceInfo deviceOut(QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).at(0));
qDebug()<<"Selected Output device ="<<deviceOut.deviceName();
QAudioDeviceInfo deviceIn(QAudioDeviceInfo::availableDevices(QAudio::AudioInput).at(0));
qDebug()<<"Selected input device ="<<deviceIn.deviceName();
audioOut = new QAudioOutput(deviceOut,formatOut,0);
audioIn = new QAudioInput (deviceIn, formatIn,0);
foreach(const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioInput))
{
qDebug() << "\nSuported Input devices";
qDebug() << "\nDevice name: " << deviceInfo.deviceName();
qDebug() << "Supported channel count: " << deviceInfo.supportedChannelCounts();
qDebug() << "Supported Codec: " << deviceInfo.supportedCodecs();
qDebug() << "Supported byte order: " << deviceInfo.supportedByteOrders();
qDebug() << "Supported Sample Rate: " << deviceInfo.supportedSampleRates();
qDebug() << "Supported Sample Size: " << deviceInfo.supportedSampleSizes();
qDebug() << "Supported Sample Type: " << deviceInfo.supportedSampleTypes();
qDebug() << "Preferred Device settings:" << deviceInfo.preferredFormat();
}
foreach(const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
{
qDebug() << "\nSuported output devices";
qDebug() << "Device name: " << deviceInfo.deviceName();
qDebug() << "Supported channel count: " << deviceInfo.supportedChannelCounts();
qDebug() << "Supported Codec: " << deviceInfo.supportedCodecs();
qDebug() << "Supported byte order: " << deviceInfo.supportedByteOrders();
qDebug() << "Supported Sample Rate: " << deviceInfo.supportedSampleRates();
qDebug() << "Supported Sample Size: " << deviceInfo.supportedSampleSizes();
qDebug() << "Supported Sample Type: " << deviceInfo.supportedSampleTypes();
qDebug() << "Preferred Device settings:" << deviceInfo.preferredFormat();
}
buff.resize(0x10000);
pbuff=buff.data();
RXbuff=0;
qDebug()<<"File open"<<open(QIODevice::ReadWrite);
qDebug()<<"is device Sequential="<<isSequential();
audioIn->start(this);
audioOut->setVolume(0.5);
audioOut->start(this);
}
qint64 myAudio::readData(char *data, qint64 len)
{
static quint64 TXbuff=0;
qint64 total = 0;
while (len > total && RXbuff>TXbuff)
{
memcpy(&data[total],&pbuff[TXbuff%0x10000],2);
TXbuff+=2;
total+=2;
}
return total;
}
qint64 myAudio::writeData(const char *data, qint64 len)
{
int total=0;
while (len > total)
{
memcpy(&pbuff[RXbuff%0x10000],&data[total], 2);
RXbuff+=2;
total+=2;
}
return (total);
}
qint64 myAudio::bytesAvailable() const{return 0;}