1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00
LibQQt/test/voicetest/mainwindow.cpp
tianduanrui 1dde4251cd fix
纠正QQtDictNode list模式内外空间不分离的问题。
纠正QQtSoundEffect在机械硬盘和SSD上不同表现的问题。
2018-04-17 19:32:16 +08:00

558 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qqtaudiomanager.h>
#include <qqtcore.h>
#include <qsound.h>
#include <qsoundeffect.h>
#include <qqtsoundeffect.h>
#include <qqtframe.h>
MainWindow::MainWindow ( QWidget* parent ) :
QMainWindow ( parent ),
ui ( new Ui::MainWindow )
{
ui->setupUi ( this );
connect ( &manager, SIGNAL ( readyRead() ), this, SLOT ( readyRead() ) );
connect ( &wavRecManager, SIGNAL ( readyRead() ), this, SLOT ( wavRecReadyRead() ) );
connect ( &wavFileManager, SIGNAL ( readyRead() ), this, SLOT ( wavFileReadyRead() ) );
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();
ui->inHS->setRange ( 0, 100 );
ui->inHS->setValue ( 100 );
ui->outHS->setRange ( 0, 100 );
ui->outHS->setValue ( 100 );
//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 ( res ( "9733.wav" ) ) );
//e.play();
//响
//QSound::play ( res ( "9733.wav" ) );
//响
QQtWavSoundEffect e1;
//e1.play ( res ( "9733.wav" ) );
//响
//QApplication::beep();
//建议初始化
QQtWavSoundEffect::Instance ( this );
//可以多次循环调用。
QQtWavSound ( res ( "9733.wav" ) );
//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::wavRecReadyRead()
{
QByteArray bytes = wavRecManager.readAll();
//pline() << "recording:" << bytes.size();
wavFileManager.write ( bytes );
}
void MainWindow::wavFileReadyRead()
{
QByteArray bytes = wavFileManager.readAll();
//pline() << "playing:" << bytes.size();
wavRecManager.write ( bytes );
}
void MainWindow::on_pushButton_3_clicked()
{
manager.stopInput();
manager.stopOutput();
}
/*bug:Qt 设置音量会报错退出*/
void MainWindow::on_inHS_valueChanged ( int value )
{
return;
if ( !manager.inputDevice() )
return;
qreal linearVolume;
// qreal linearVolume = QAudio::convertVolume ( value / qreal ( 100.0 ),
// QAudio::LogarithmicVolumeScale,
// QAudio::LinearVolumeScale );
// pline() << "输入音量" << value << linearVolume << qRound ( linearVolume * 100 ) ;
manager.inputManager()->setVolume ( qRound ( linearVolume * 100 ) );
}
/*bug:Qt 设置音量会报错退出*/
void MainWindow::on_outHS_valueChanged ( int value )
{
return;
if ( !manager.outputDevice() )
return;
qreal vol = qreal ( value ) / 100;
pline() << "输出音量" << vol ;
manager.outputManager()->setVolume ( vol );
}
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();
}
void MainWindow::on_pushButton_5_clicked()
{
QString name = QQtAudioManager::defaultOutputDevice().deviceName();
if ( ui->outputListWidget->currentIndex().isValid() )
name = ui->outputListWidget->currentIndex().data().toString();
QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
QQtWavSoundEffect::Instance()->useCustomOutputDevice ( devOut );
QQtWavSound()->setLoops ( 3 );
QQtWavSound ( res ( "9733.wav" ) );
}
void MainWindow::on_pushButton_6_clicked()
{
QString name = QQtAudioManager::defaultOutputDevice().deviceName();
if ( ui->outputListWidget->currentIndex().isValid() )
name = ui->outputListWidget->currentIndex().data().toString();
QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
QQtWavSoundEffect::Instance()->useCustomOutputDevice ( devOut );
QQtWavSound ( res ( "9763.wav" ) );
//QSound::play ( res("9763.wav"));
}
void MainWindow::on_pushButton_7_clicked()
{
QString name = QQtAudioManager::defaultOutputDevice().deviceName();
if ( ui->outputListWidget->currentIndex().isValid() )
name = ui->outputListWidget->currentIndex().data().toString();
QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
QQtWavSoundEffect::Instance()->useCustomOutputDevice ( devOut );
QQtWavSound()->setLoops ( 1 );
QQtWavSound ( res ( "9612.wav" ) );
}
#define TMPFILE "./temp.wav"
void MainWindow::on_pushButton_8_clicked()
{
//不需要停止录音?需要
//android 不支持./temp.wav....
//record
QAudioDeviceInfo input = QQtAudioManager::defaultInputDevice();
wavRecManager.inputDeviceInfo() = input;
wavRecManager.inputAudioFormat() = input.preferredFormat();
//save wav file
wavFileManager.outputAudioFormat() = wavRecManager.inputAudioFormat();
wavFileManager.setOutputSourceFile ( TMPFILE );
pline() << "record:" << wavRecManager.inputDeviceInfo().deviceName() << wavRecManager.inputAudioFormat();
pline() << "save:" << wavFileManager.outputSourceFile() << wavFileManager.outputAudioFormat();
//内部存在自动关停。对wav写自动关停会导致文件被重写。这个函数是录音重新开始所以可以自动关停。
wavFileManager.startOutput();
wavRecManager.startInput();
}
void MainWindow::on_pushButton_9_clicked()
{
//不需要停止放音?需要
//read wav file
wavFileManager.setInputSourceFile ( TMPFILE );
//play record
wavRecManager.outputAudioFormat() = wavFileManager.inputAudioFormat();
wavRecManager.outputDeviceInfo() = QQtAudioManager::defaultOutputDevice();
pline() << "file:" << wavFileManager.inputSourceFile() << wavFileManager.inputAudioFormat();
pline() << "play:" << wavRecManager.outputDeviceInfo().deviceName() << wavRecManager.outputAudioFormat();
//内部存在自动关停。
wavRecManager.startOutput();
wavFileManager.startInput();
}
void MainWindow::on_pushButton_10_clicked()
{
wavRecManager.stopInput();
wavFileManager.stopOutput();
}
void MainWindow::on_pushButton_11_clicked()
{
wavFileManager.stopInput();
wavRecManager.stopOutput();
}
void MainWindow::on_pushButton_12_clicked()
{
//android support 16bit but 24bit
QQtWavSoundEffect* e0 = QQtWavSound();
e0->setTimerInterval ( 100 );
QQtWavSound ( res ( "9767.wav" ) );
}