mirror of
https://gitee.com/drabel/LibQQt.git
synced 2025-01-04 10:18:44 +08:00
387 lines
12 KiB
C++
387 lines
12 KiB
C++
#include "mainwindow.h"
|
||
#include "ui_mainwindow.h"
|
||
#include <qqtaudiomanager.h>
|
||
#include <qqtcore.h>
|
||
#include <qsound.h>
|
||
#include <qsoundeffect.h>
|
||
#include <qqtframe.h>
|
||
|
||
MainWindow::MainWindow ( QWidget* parent ) :
|
||
QMainWindow ( parent ),
|
||
ui ( new Ui::MainWindow )
|
||
{
|
||
ui->setupUi ( this );
|
||
|
||
connect ( &manager, SIGNAL ( readyRead() ), this, SLOT ( readyRead() ) );
|
||
|
||
QList<QAudioDeviceInfo> ladInfo;
|
||
ladInfo = QAudioDeviceInfo::availableDevices ( QAudio::AudioInput );
|
||
QListIterator<QAudioDeviceInfo> itor ( ladInfo );
|
||
pline() << "本机音频输入设备列表";
|
||
|
||
while ( itor.hasNext() )
|
||
pline() << itor.next().deviceName();
|
||
|
||
pline() << "默认输入设备" << QAudioDeviceInfo::defaultInputDevice().deviceName();
|
||
pline() << "输入设备详细信息";
|
||
itor.toFront();
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QAudioDeviceInfo adInfo = itor.next();
|
||
pline() << adInfo.deviceName();
|
||
pline() << adInfo.supportedByteOrders();
|
||
pline() << adInfo.supportedChannelCounts();
|
||
pline() << adInfo.supportedCodecs();
|
||
pline() << adInfo.supportedSampleRates();
|
||
pline() << adInfo.supportedSampleSizes();
|
||
pline() << adInfo.supportedSampleTypes();
|
||
}
|
||
|
||
|
||
QList<QAudioDeviceInfo> ladOutputInfo;
|
||
ladOutputInfo = QAudioDeviceInfo::availableDevices ( QAudio::AudioOutput );
|
||
QListIterator<QAudioDeviceInfo> itor2 ( ladOutputInfo );
|
||
pline() << "本机音频输出设备列表";
|
||
|
||
while ( itor2.hasNext() )
|
||
pline() << itor2.next().deviceName();
|
||
|
||
pline() << "默认输出设备" << QAudioDeviceInfo::defaultOutputDevice().deviceName();
|
||
pline() << "输出设备详细信息";
|
||
itor2.toFront();
|
||
|
||
while ( itor2.hasNext() )
|
||
{
|
||
QAudioDeviceInfo adInfo = itor2.next();
|
||
pline() << adInfo.deviceName();
|
||
pline() << adInfo.supportedByteOrders();
|
||
pline() << adInfo.supportedChannelCounts();
|
||
pline() << adInfo.supportedCodecs();
|
||
pline() << adInfo.supportedSampleRates();
|
||
pline() << adInfo.supportedSampleSizes();
|
||
pline() << adInfo.supportedSampleTypes();
|
||
}
|
||
|
||
|
||
pline() << "..........................";
|
||
|
||
connect ( ui->inputListWidget->selectionModel(), SIGNAL ( currentRowChanged ( QModelIndex, QModelIndex ) ),
|
||
this, SLOT ( currentInputRowChanged ( QModelIndex, QModelIndex ) ) );
|
||
connect ( ui->outputListWidget->selectionModel(), SIGNAL ( currentRowChanged ( QModelIndex, QModelIndex ) ),
|
||
this, SLOT ( currentOutputRowChanged ( QModelIndex, QModelIndex ) ) );
|
||
|
||
// on_pushButton_2_clicked();
|
||
// ui->inputListWidget->setCurrentRow ( 0 );
|
||
// ui->outputListWidget->setCurrentRow ( 0 );
|
||
// ui->inputListWidget->setFocus();
|
||
//pline() << QSoundEffect::supportedMimeTypes();
|
||
|
||
QSoundEffect e;
|
||
e.setLoopCount ( 1 );
|
||
e.setVolume ( 0.9f );
|
||
e.setMuted ( false );
|
||
|
||
//不响
|
||
QUrl u;
|
||
u.setUrl ( "http://xmdx.sc.chinaz.com/Files/DownLoad/sound1/201802/9733.wav" );
|
||
e.setSource ( u );
|
||
//e.play();
|
||
|
||
//响
|
||
e.setSource ( QUrl::fromLocalFile ( conf_res ( "9733.wav" ) ) );
|
||
//e.play();
|
||
|
||
//响
|
||
//QSound::play ( conf_res ( "9733.wav" ) );
|
||
|
||
//响
|
||
//QApplication::beep();
|
||
|
||
//QQtSleep ( 3000 );
|
||
}
|
||
|
||
MainWindow::~MainWindow()
|
||
{
|
||
delete ui;
|
||
}
|
||
|
||
QAudioDeviceInfo MainWindow::findInputAudioDeviceInfoByName ( QString devName )
|
||
{
|
||
QList<QAudioDeviceInfo> ladInfo;
|
||
ladInfo = QQtAudioManager::availableInputDevices();
|
||
QListIterator<QAudioDeviceInfo> itor ( ladInfo );
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QAudioDeviceInfo adInfo = itor.next();
|
||
|
||
if ( devName == adInfo.deviceName() )
|
||
return adInfo;
|
||
}
|
||
}
|
||
|
||
QAudioDeviceInfo MainWindow::findOutputAudioDeviceInfoByName ( QString devName )
|
||
{
|
||
QList<QAudioDeviceInfo> ladInfo;
|
||
ladInfo = QQtAudioManager::availableOutputDevices();
|
||
QListIterator<QAudioDeviceInfo> itor ( ladInfo );
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QAudioDeviceInfo adInfo = itor.next();
|
||
|
||
if ( devName == adInfo.deviceName() )
|
||
return adInfo;
|
||
}
|
||
}
|
||
|
||
|
||
void MainWindow::on_pushButton_2_clicked()
|
||
{
|
||
ui->inputListWidget->clear();
|
||
|
||
QList<QAudioDeviceInfo> ladInfo;
|
||
ladInfo = QQtAudioManager::availableInputDevices();
|
||
QListIterator<QAudioDeviceInfo> itor ( ladInfo );
|
||
pline() << "本机音频输入设备列表";
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QAudioDeviceInfo adInfo = itor.next();
|
||
pline() << adInfo.deviceName();
|
||
ui->inputListWidget->addItem ( adInfo.deviceName() );
|
||
}
|
||
|
||
|
||
ui->outputListWidget->clear();
|
||
|
||
QList<QAudioDeviceInfo> ladOutputInfo;
|
||
ladOutputInfo = QQtAudioManager::availableOutputDevices();
|
||
QListIterator<QAudioDeviceInfo> itor2 ( ladOutputInfo );
|
||
pline() << "本机音频输出设备列表";
|
||
|
||
while ( itor2.hasNext() )
|
||
{
|
||
QAudioDeviceInfo adInfo = itor2.next();
|
||
pline() << adInfo.deviceName();
|
||
ui->outputListWidget->addItem ( adInfo.deviceName() );
|
||
}
|
||
|
||
}
|
||
|
||
void MainWindow::currentInputRowChanged ( QModelIndex cur, QModelIndex )
|
||
{
|
||
/*在清空设备列表时,clear函数,会调用多次这个函数。在这里用cur valid加以过滤,否则,程序会崩溃退出。*/
|
||
if ( !cur.isValid() )
|
||
return;
|
||
|
||
ui->inBit->clear();
|
||
ui->inChn->clear();
|
||
ui->intRate->clear();
|
||
|
||
|
||
QString name = cur.data().toString();
|
||
QAudioDeviceInfo dev = findInputAudioDeviceInfoByName ( name );
|
||
|
||
if ( dev.isNull() )
|
||
return;
|
||
|
||
QList<int> size = dev.supportedSampleSizes();
|
||
QListIterator<int> itor ( size );
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QString s0 = QString::number ( itor.next() );
|
||
ui->inBit->addItem ( s0 );
|
||
}
|
||
|
||
itor = dev.supportedChannelCounts();
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QString s0 = QString::number ( itor.next() );
|
||
ui->inChn->addItem ( s0 );
|
||
}
|
||
|
||
itor = dev.supportedSampleRates();
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QString s0 = QString::number ( itor.next() );
|
||
ui->intRate->addItem ( s0 );
|
||
}
|
||
|
||
}
|
||
|
||
void MainWindow::currentOutputRowChanged ( QModelIndex cur, QModelIndex )
|
||
{
|
||
if ( !cur.isValid() )
|
||
return;
|
||
|
||
ui->outBit->clear();
|
||
ui->outChn->clear();
|
||
ui->outRate->clear();
|
||
|
||
|
||
QString name = cur.data().toString();
|
||
QAudioDeviceInfo dev = findOutputAudioDeviceInfoByName ( name );
|
||
|
||
if ( dev.isNull() )
|
||
return;
|
||
|
||
QList<int> size = dev.supportedSampleSizes();
|
||
QListIterator<int> itor ( size );
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QString s0 = QString::number ( itor.next() );
|
||
ui->outBit->addItem ( s0 );
|
||
}
|
||
|
||
itor = dev.supportedChannelCounts();
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QString s0 = QString::number ( itor.next() );
|
||
ui->outChn->addItem ( s0 );
|
||
}
|
||
|
||
itor = dev.supportedSampleRates();
|
||
|
||
while ( itor.hasNext() )
|
||
{
|
||
QString s0 = QString::number ( itor.next() );
|
||
ui->outRate->addItem ( s0 );
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 处理声音三要点
|
||
* 声音的格式 ,也就是声音三要素,输入一个、输出一个,manager对其分开管理,但是建议用户合并为一个置等。通道数、采样位宽、采样率
|
||
* 声音设备 ,输入一个、输出一个,manager管理start\stop等接口,manager内部的inputManager和outputManager负责其他接口。
|
||
* 声音设备的读写出入口 ,manager管理,包括可读信号和写入函数。
|
||
*/
|
||
void MainWindow::on_pushButton_clicked()
|
||
{
|
||
/*这里是自定义输入、输出设备*/
|
||
QString name = QQtAudioManager::defaultInputDevice().deviceName();
|
||
|
||
if ( ui->inputListWidget->currentIndex().isValid() )
|
||
name = ui->inputListWidget->currentIndex().data().toString();
|
||
|
||
QAudioDeviceInfo dev = findInputAudioDeviceInfoByName ( name );
|
||
|
||
name = QQtAudioManager::defaultOutputDevice().deviceName();
|
||
|
||
if ( ui->outputListWidget->currentIndex().isValid() )
|
||
name = ui->outputListWidget->currentIndex().data().toString();
|
||
|
||
QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
|
||
|
||
/*使用默认输入、输出设备*/
|
||
//如果开启这段代码,页面上的输入、输出设备选择,就仅仅是个显示了,不具备操作能力。
|
||
/*
|
||
dev = QQtAudioManager::defaultInputDevice();
|
||
devOut = QQtAudioManager::defaultOutputDevice();
|
||
*/
|
||
|
||
//把设备设进manager去
|
||
manager.inputDeviceInfo() = dev;
|
||
manager.outputDeviceInfo() = devOut;
|
||
|
||
//这里保证输入、输出使用格式相等 或者 不同
|
||
//如果格式不同,在mac电脑上本地输入输出设备是可以使用的,但是对于连接的语音蓝牙话筒,却是不可以使用的,原因未知。
|
||
//格式相同的时候,实在是太好用啦。
|
||
//这个建议默认就相同,但是,在QQtAudioManager当中,并没有直接将其相等处理,如果用户在readyRead槽函数里,可以更改采样率进行某些特殊处理。一般不需要差异处理的,相等就行了。
|
||
// int inBit = ui->inBit->currentIndex().data().toInt();
|
||
// int inChn = ui->inChn->currentIndex().data().toInt();
|
||
// int inRate = ui->intRate->currentIndex().data().toInt();
|
||
// QAudioFormat inFmt;
|
||
// inFmt.setChannelCount ( inChn );
|
||
// inFmt.setSampleSize ( inBit );
|
||
// inFmt.setSampleRate ( inRate );
|
||
// inFmt.setCodec ( "audio/pcm" );
|
||
// manager.inputAudioFormat() = inFmt;
|
||
|
||
QAudioFormat outFmt = manager.outputDeviceInfo().preferredFormat();
|
||
|
||
int outBit = outFmt.sampleSize(), outChn = outFmt.channelCount(), outRate = outFmt.sampleRate();
|
||
|
||
if ( ui->outBit->currentIndex().isValid() )
|
||
outBit = ui->outBit->currentIndex().data().toInt();
|
||
|
||
if ( ui->outChn->currentIndex().isValid() )
|
||
outChn = ui->outChn->currentIndex().data().toInt();
|
||
|
||
if ( ui->outRate->currentIndex().isValid() )
|
||
outRate = ui->outRate->currentIndex().data().toInt();
|
||
|
||
outFmt.setChannelCount ( outChn );
|
||
outFmt.setSampleSize ( outBit );
|
||
outFmt.setSampleRate ( outRate );
|
||
outFmt.setCodec ( "audio/pcm" );
|
||
|
||
manager.inputAudioFormat() = outFmt;
|
||
manager.outputAudioFormat() = outFmt;
|
||
|
||
pline() << "in prefer" << dev.preferredFormat().channelCount() << dev.preferredFormat().sampleRate() <<
|
||
dev.preferredFormat().sampleSize();
|
||
|
||
pline() << "out prefer" << devOut.preferredFormat().channelCount() << devOut.preferredFormat().sampleRate() <<
|
||
devOut.preferredFormat().sampleSize();
|
||
|
||
pline() << "in" << manager.inputAudioFormat().channelCount() << manager.inputAudioFormat().sampleRate() <<
|
||
manager.inputAudioFormat().sampleSize();
|
||
|
||
pline() << "out" << manager.outputAudioFormat().channelCount() << manager.outputAudioFormat().sampleRate() <<
|
||
manager.outputAudioFormat().sampleSize();
|
||
|
||
manager.startInput();
|
||
manager.startOutput();
|
||
}
|
||
|
||
void MainWindow::readyRead()
|
||
{
|
||
//这里是用户实现,任何用户希望做的事情,都在这里做完。
|
||
//可以 录音、保存文件
|
||
//可以 直接播放
|
||
//可以 混音 +保存 +播放...
|
||
//可以 消音
|
||
//可以 将pcm转换为其他格式音频
|
||
//可以 降噪
|
||
//可以 ...
|
||
//ptime();//11-12ms 是个10ms timer
|
||
QByteArray bytes = manager.readAll();
|
||
manager.write ( bytes );
|
||
}
|
||
|
||
void MainWindow::on_pushButton_3_clicked()
|
||
{
|
||
manager.stopInput();
|
||
manager.stopOutput();
|
||
}
|
||
|
||
void MainWindow::on_pushButton_4_clicked()
|
||
{
|
||
manager.inputAudioFormat() = QQtAudioManager::defaultOutputDevice().preferredFormat();
|
||
manager.outputAudioFormat() = QQtAudioManager::defaultOutputDevice().preferredFormat();
|
||
|
||
pline() << "in prefer" << QQtAudioManager::defaultInputDevice().preferredFormat().channelCount() <<
|
||
QQtAudioManager::defaultInputDevice().preferredFormat().sampleRate() <<
|
||
QQtAudioManager::defaultInputDevice().preferredFormat().sampleSize();
|
||
|
||
pline() << "out prefer" << QQtAudioManager::defaultOutputDevice().preferredFormat().channelCount() <<
|
||
QQtAudioManager::defaultOutputDevice().preferredFormat().sampleRate() <<
|
||
QQtAudioManager::defaultOutputDevice().preferredFormat().sampleSize();
|
||
|
||
pline() << "in" << manager.inputAudioFormat().channelCount() << manager.inputAudioFormat().sampleRate() <<
|
||
manager.inputAudioFormat().sampleSize();
|
||
|
||
pline() << "out" << manager.outputAudioFormat().channelCount() << manager.outputAudioFormat().sampleRate() <<
|
||
manager.outputAudioFormat().sampleSize();
|
||
|
||
manager.startDefaultInput();
|
||
manager.startDefaultOutput();
|
||
}
|