Название: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 10:12
[РЕШЕНО]Доброго времени суток. Пишу плейер для нескольких аудиокарт, он состоит из двух дек и сэмплера, всё это реализовано на 3-х QTableWidget. Проект в тестовом режиме, поэтому всё умещается в mainwindow.h и mainwindow.cpp (куча кода), + позаимствовал парсер wav файлов из примеров qt (wav.h wav.cpp utils.h). В кратце, создаётся 3 аудиовыхода (QAudioOutput *q_audio1, *q_audio2, *q_audio3), на которые подаются pcm из соответствующих QFile* (playingFile1,playingFile2,playingFile3). Всё работает, но есть досадный артефакт: когда я вызываю метод QAudioOutput::stop() для одного из проигрывающих выходов, на другом проигрывающем выходе возникает миллисекундная заминка, как будто на мгновение сработала пауза. Что это может быть? Может процесс проигрывания нужно пихать в QThread для каждого аудиовыхода? И вообще, как могут соприкасаться объекты класса QAudioOutput работающие на разных QAudioDeviceInfo, т.е. я останавливаю проигрывание на одной звуковой карте, а щелчок слышу на другой, хотя проигрывание на ней идёт дальше?
Если нужно, могу привести полностью код программы, правда, mainwindow.cpp это 1524 строки и не всё будет понятно, я не писал комментарии.
Заранее спасибо за помощь.
Название: Re: проблема с QAudioOutput
Отправлено: Bepec от Сентябрь 28, 2014, 13:59
1,5 к строк это ничто :) Выкладывайте, мб кто и посмотрит. Аудио специалистов я тут пока не встречал, но знающие люди есть :)
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 14:47
Итак, mainwindow.h: #ifndef MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow> #include <QThread> #include <QTimer> #include <QFile> #include <QFileDialog> #include <QByteArray> #include <QTime> #include <QSlider> #include <QtMultimedia> #include <QAudio> #include <QAudioOutput> #include <QAudioDeviceInfo> #include <QVector> #include "exitdialog.h" #include "wavfile.h"
namespace Ui { class MainWindow; }
class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; QAudioDeviceInfo q_device,q_device2,q_device3; QAudioFormat q_format,q_format2,q_format3; QAudioOutput *q_audio,*q_audio2,*q_audio3; QFile *preFile,*preFile2,*nowPlayingFile,*nowPlayingFile2,*nowPlayingFile3; QFileInfo inputFile,inputFile2,inputFile3,*OpenedFile,*OpenedFile2,outputFile; QString errorMessage,errorMessage1,path; QThread *infoThread; QThread *infoThread2; QThread *infoThread3; QTimer *fadeTimer,*fadeTimer2,*fadeOutTimer,*fadeOutTimer2,*sfTimer,*sbTimer,*sfTimer2,*sbTimer2,*tTimer,*tTimer2,*tTimer3; qreal Volume,Volume2,Volume3; QVector<QFile*> Array; bool autocross, autocross2; exitDialog *d;
private slots: void keyReleaseEvent(QKeyEvent *); void setDevice(int index); void setDevice2(int index); void setDevice3(int index); void addFiles(); void addFiles2(); void addFiles3(); void replaceFile(); void replaceFile2(); void replaceFile3(); void addRow(); void addRow2(); void itemRemove(); void itemRemove2(); void itemRemove3(); void itemClear(); void itemClear3(); void loadList(QString fileName); void loadList2(); void convertList(); void openPlaylist(); void saveList(); void saveList2(); void itemPlay(); void itemPlay2(); void itemStop(); void itemStop2(); void itemStop3(); void itemPause(); void itemPause2(); void itemUnPause(); void itemUnPause2(); void fadeOut(); void fadeOut2(); void fade(); void fadeIn(); void fadeIn2(); void fade2(); void crossFade(); void crossFade2(); void seekF(); void seekB(); void seekF2(); void seekB2(); void updatePos(); void updatePos2(); void updatePos3(); void setPos(); void setPos2(); void setVolume(); void setVolume2(); void f1(); void f2(); void f3(); void f4(); void f5(); void f6(); void aboutToClose(); void closeEvent(QCloseEvent *event);
signals: void StopFadeSignal(); void StopFadeSignal2(); void StopFadeOut(); void StopFadeOut2(); };
#endif // MAINWINDOW_H
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 14:50
mainwindow.cpp первая часть: #include "mainwindow.h" #include "ui_mainwindow.h" #include "nonedittablecolumndelegate.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); foreach(const QAudioDeviceInfo &devInfo,QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) { ui->deviceBox->addItem(devInfo.deviceName(),qVariantFromValue(devInfo)); ui->deviceBox_2->addItem(devInfo.deviceName(),qVariantFromValue(devInfo)); ui->deviceBox_3->addItem(devInfo.deviceName(),qVariantFromValue(devInfo)); } q_device = QAudioDeviceInfo::defaultOutputDevice(); q_device2 = QAudioDeviceInfo::defaultOutputDevice(); q_device3 = QAudioDeviceInfo::defaultOutputDevice(); q_format.setSampleRate(44100); q_format.setSampleSize(16); q_format.setChannelCount(2); q_format.setCodec("audio/pcm"); q_format.setByteOrder(QAudioFormat::LittleEndian); q_format.setSampleType(QAudioFormat::UnSignedInt); q_format2.setSampleRate(44100); q_format2.setSampleSize(16); q_format2.setChannelCount(2); q_format2.setCodec("audio/pcm"); q_format2.setByteOrder(QAudioFormat::LittleEndian); q_format2.setSampleType(QAudioFormat::UnSignedInt); q_format3.setSampleRate(44100); q_format3.setSampleSize(16); q_format3.setChannelCount(2); q_format3.setCodec("audio/pcm"); q_format3.setByteOrder(QAudioFormat::LittleEndian); q_format3.setSampleType(QAudioFormat::UnSignedInt); q_audio = new QAudioOutput(q_device,q_format,this); q_audio2 = new QAudioOutput(q_device2,q_format2,this); q_audio3 = new QAudioOutput(q_device3,q_format3,this); ui->lcdNumber->display("00:00"); ui->lcdNumber_2->display("00:00"); ui->totalTimeDisp->display("00:00"); ui->totalTimeDisp_2->display("00:00"); ui->volumeDisp->display("100"); ui->volumeDisp_2->display("100"); ui->dial->setSliderPosition(100); ui->dial_2->setSliderPosition(100); errorMessage = "THERE IS NO MEDIAFILE!!!"; errorMessage1 = "Playlist IS EMPTY!!!"; fadeTimer = new QTimer(this); fadeTimer->setInterval(100); fadeTimer->stop(); fadeTimer2 = new QTimer(this); fadeTimer2->setInterval(100); fadeTimer2->stop(); fadeOutTimer = new QTimer(this); fadeOutTimer->setInterval(100); fadeOutTimer->stop(); fadeOutTimer2 = new QTimer(this); fadeOutTimer2->setInterval(100); fadeOutTimer2->stop(); sfTimer = new QTimer(this); sfTimer->setInterval(100); sfTimer->stop(); sfTimer2 = new QTimer(this); sfTimer2->setInterval(100); sfTimer2->stop(); sbTimer = new QTimer(this); sbTimer->setInterval(100); sbTimer->stop(); sbTimer2 = new QTimer(this); sbTimer2->setInterval(100); sbTimer2->stop(); infoThread = new QThread; tTimer = new QTimer(0); tTimer->setInterval(20); tTimer->stop(); tTimer->moveToThread(infoThread); infoThread2 = new QThread; tTimer2 = new QTimer(0); tTimer2->setInterval(20); tTimer2->stop(); tTimer2->moveToThread(infoThread2); infoThread3 = new QThread; tTimer3 = new QTimer(0); tTimer3->setInterval(20); tTimer3->stop(); tTimer3->moveToThread(infoThread3); connect(infoThread,SIGNAL(started()),tTimer,SLOT(start())); connect(tTimer,SIGNAL(timeout()),this,SLOT(updatePos())); connect(infoThread,SIGNAL(finished()),tTimer,SLOT(stop())); connect(infoThread2,SIGNAL(started()),tTimer2,SLOT(start())); connect(tTimer2,SIGNAL(timeout()),this,SLOT(updatePos2())); connect(infoThread2,SIGNAL(finished()),tTimer2,SLOT(stop())); connect(infoThread3,SIGNAL(started()),tTimer3,SLOT(start())); connect(tTimer3,SIGNAL(timeout()),this,SLOT(updatePos3())); connect(infoThread3,SIGNAL(finished()),tTimer3,SLOT(stop())); connect(sfTimer,SIGNAL(timeout()),this,SLOT(seekF())); connect(sbTimer,SIGNAL(timeout()),this,SLOT(seekB())); connect(sfTimer2,SIGNAL(timeout()),this,SLOT(seekF2())); connect(sbTimer2,SIGNAL(timeout()),this,SLOT(seekB2())); connect(ui->seekFButton,SIGNAL(pressed()),sfTimer,SLOT(start())); connect(ui->seekFButton,SIGNAL(released()),sfTimer,SLOT(stop())); connect(ui->seekFButton_2,SIGNAL(pressed()),sfTimer2,SLOT(start())); connect(ui->seekFButton_2,SIGNAL(released()),sfTimer2,SLOT(stop())); connect(ui->seekBButton,SIGNAL(pressed()),sbTimer,SLOT(start())); connect(ui->seekBButton,SIGNAL(released()),sbTimer,SLOT(stop())); connect(ui->seekBButton_2,SIGNAL(pressed()),sbTimer2,SLOT(start())); connect(ui->seekBButton_2,SIGNAL(released()),sbTimer2,SLOT(stop())); connect(ui->deviceBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setDevice(int))); connect(ui->deviceBox_2,SIGNAL(currentIndexChanged(int)),this,SLOT(setDevice2(int))); connect(ui->deviceBox_3,SIGNAL(currentIndexChanged(int)),this,SLOT(setDevice3(int))); connect(ui->fileButton,SIGNAL(clicked()),this,SLOT(addFiles2())); connect(ui->fileButton_2,SIGNAL(clicked()),this,SLOT(addFiles())); connect(ui->fileButton_3,SIGNAL(clicked()),this,SLOT(addFiles3())); connect(ui->replaceButton,SIGNAL(clicked()),this,SLOT(replaceFile())); connect(ui->replaceButton_2,SIGNAL(clicked()),this,SLOT(replaceFile2())); connect(ui->replaceButton_3,SIGNAL(clicked()),this,SLOT(replaceFile3())); connect(ui->loadButton,SIGNAL(clicked()),this,SLOT(addRow())); connect(ui->loadButton_2,SIGNAL(clicked()),this,SLOT(addRow2())); connect(ui->removeButton,SIGNAL(clicked()),this,SLOT(itemRemove())); connect(ui->removeButton_2,SIGNAL(clicked()),this,SLOT(itemRemove2())); connect(ui->loadlistButton,SIGNAL(clicked()),this,SLOT(openPlaylist())); connect(ui->loadlistButton_2,SIGNAL(clicked()),this,SLOT(loadList2())); connect(ui->saveButton,SIGNAL(clicked()),this,SLOT(saveList())); connect(ui->saveButton_2,SIGNAL(clicked()),this,SLOT(saveList2())); connect(ui->clearButton,SIGNAL(clicked()),this,SLOT(itemClear())); connect(ui->clearButton_3,SIGNAL(clicked()),this,SLOT(itemClear3())); connect(ui->playButton,SIGNAL(clicked()),this,SLOT(itemPlay())); connect(ui->playButton_2,SIGNAL(clicked()),this,SLOT(itemPlay2())); connect(ui->stopButton,SIGNAL(clicked()),this,SLOT(itemStop())); connect(ui->stopButton_2,SIGNAL(clicked()),this,SLOT(itemStop2())); connect(ui->SsButton,SIGNAL(clicked()),this,SLOT(itemStop3())); connect(ui->pauseButton,SIGNAL(clicked()),this,SLOT(itemPause())); connect(ui->pauseButton_2,SIGNAL(clicked()),this,SLOT(itemPause2())); connect(ui->altplayButton,SIGNAL(clicked()),this,SLOT(itemUnPause())); connect(ui->altplayButton_2,SIGNAL(clicked()),this,SLOT(itemUnPause2())); connect(fadeOutTimer,SIGNAL(timeout()),this,SLOT(fadeOut())); connect(ui->fadeOutButton,SIGNAL(clicked()),fadeOutTimer,SLOT(start())); connect(fadeOutTimer2,SIGNAL(timeout()),this,SLOT(fadeOut2())); connect(ui->fadeOutButton_2,SIGNAL(clicked()),fadeOutTimer2,SLOT(start())); connect(fadeTimer,SIGNAL(timeout()),this,SLOT(fade())); connect(ui->fadeButton,SIGNAL(clicked()),fadeTimer,SLOT(start())); connect(fadeTimer2,SIGNAL(timeout()),this,SLOT(fade2())); connect(ui->fadeButton_2,SIGNAL(clicked()),fadeTimer2,SLOT(start())); connect(ui->fadeInButton,SIGNAL(clicked()),this,SLOT(fadeIn())); connect(ui->fadeInButton_2,SIGNAL(clicked()),this,SLOT(fadeIn2())); connect(ui->seekSlider,SIGNAL(sliderMoved(int)),this,SLOT(setPos())); connect(ui->seekSlider_2,SIGNAL(sliderMoved(int)),this,SLOT(setPos2())); connect(ui->dial,SIGNAL(sliderMoved(int)),this,SLOT(setVolume())); connect(ui->dial_2,SIGNAL(sliderMoved(int)),this,SLOT(setVolume2())); connect(ui->crossButton,SIGNAL(clicked()),this,SLOT(crossFade())); connect(ui->crossButton_2,SIGNAL(clicked()),this,SLOT(crossFade2())); connect(ui->fButton,SIGNAL(clicked()),this,SLOT(f1())); connect(ui->fButton_2,SIGNAL(clicked()),this,SLOT(f2())); connect(ui->fButton_3,SIGNAL(clicked()),this,SLOT(f3())); connect(ui->fButton_4,SIGNAL(clicked()),this,SLOT(f4())); connect(ui->fButton_5,SIGNAL(clicked()),this,SLOT(f5())); connect(ui->fButton_6,SIGNAL(clicked()),this,SLOT(f6())); connect(this,SIGNAL(StopFadeSignal()),fadeTimer,SLOT(stop())); connect(this,SIGNAL(StopFadeSignal2()),fadeTimer2,SLOT(stop())); connect(this,SIGNAL(StopFadeOut()),fadeOutTimer,SLOT(stop())); connect(this,SIGNAL(StopFadeOut2()),fadeOutTimer2,SLOT(stop())); connect(ui->convertButton,SIGNAL(clicked()),this,SLOT(convertList())); connect(ui->closeButton,SIGNAL(clicked()),this,SLOT(aboutToClose())); ui->tableWidget->setItemDelegateForColumn(0,new NonEditTableColumnDelegate); ui->tableWidget->setItemDelegateForColumn(2,new NonEditTableColumnDelegate); ui->tableWidget_2->setItemDelegateForColumn(0,new NonEditTableColumnDelegate); ui->tableWidget_2->setItemDelegateForColumn(2,new NonEditTableColumnDelegate); ui->tableWidget_3->setItemDelegateForColumn(0,new NonEditTableColumnDelegate); autocross = false; autocross2 = false; d = new exitDialog; connect(d,SIGNAL(SaveSignal()),this,SLOT(saveList())); connect(d,SIGNAL(SaveSampler()),this,SLOT(saveList2())); if(ui->deviceBox->count() > 1) { ui->deviceBox->setCurrentIndex(1); ui->deviceBox_2->setCurrentIndex(0); if(ui->deviceBox->count() > 2) ui->deviceBox_3->setCurrentIndex(2); } }
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 14:52
mainwindow.cpp вторая часть: void MainWindow::setDevice(int index) { q_device = ui->deviceBox->itemData(index).value<QAudioDeviceInfo>(); }
void MainWindow::setDevice2(int index) { q_device2 = ui->deviceBox_2->itemData(index).value<QAudioDeviceInfo>(); }
void MainWindow::setDevice3(int index) { q_device3 = ui->deviceBox_3->itemData(index).value<QAudioDeviceInfo>(); }
void MainWindow::addFiles() { QStringList mediaFiles; mediaFiles = QFileDialog::getOpenFileNames(this,"Load Audio Files", path, QString("Wave Files (*.wav)")); foreach(QString mediaFile,mediaFiles) { preFile = new QFile(mediaFile,this); preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); WavFile *wFile = new WavFile(this); wFile->open(preFile->fileName()); qint64 realsize = OpenedFile->size() - wFile->headerLength(); qint64 totalduration = (realsize / (wFile->fileFormat().sampleRate() * wFile->fileFormat().channelCount() * wFile->fileFormat().sampleSize() / 8)); int nMinutes = (totalduration / 60) % 60; int nSeconds = (totalduration) % 60; QTime tTime(0,nMinutes,nSeconds,0); Array.append(preFile); wFile->close(); delete wFile; const int currentRow = ui->tableWidget->rowCount(); ui->tableWidget->setRowCount(currentRow + 1); ui->tableWidget->setItem(currentRow,0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget->setItem(currentRow,1,new QTableWidgetItem("100")); ui->tableWidget->setItem(currentRow,2,new QTableWidgetItem(tTime.toString("mm:ss"))); ui->tableWidget_2->insertRow(currentRow); ui->tableWidget_2->setItem(currentRow,0,new QTableWidgetItem("")); ui->tableWidget_2->setItem(currentRow,1,new QTableWidgetItem("")); path = OpenedFile->path(); } ui->tableWidget->resizeColumnToContents(0); ui->tableWidget->setCurrentCell(ui->tableWidget->rowCount(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget->setFocus(); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } }
void MainWindow::addFiles2() { QStringList mediaFiles; mediaFiles = QFileDialog::getOpenFileNames(this,"Load Audio Files", path, QString("Wave Files (*.wav)")); foreach(QString mediaFile,mediaFiles) { preFile = new QFile(mediaFile,this); preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); WavFile *wFile = new WavFile(this); wFile->open(preFile->fileName()); qint64 realsize = OpenedFile->size() - wFile->headerLength(); qint64 totalduration = (realsize / (wFile->fileFormat().sampleRate() * wFile->fileFormat().channelCount() * wFile->fileFormat().sampleSize() / 8)); int nMinutes = (totalduration / 60) % 60; int nSeconds = (totalduration) % 60; QTime tTime(0,nMinutes,nSeconds,0); Array.append(preFile); wFile->close(); delete wFile; const int currentRow = ui->tableWidget_2->rowCount(); ui->tableWidget_2->setRowCount(currentRow + 1); ui->tableWidget_2->setItem(currentRow,0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget_2->setItem(currentRow,1,new QTableWidgetItem("100")); ui->tableWidget_2->setItem(currentRow,2,new QTableWidgetItem(tTime.toString("mm:ss"))); ui->tableWidget->insertRow(currentRow); ui->tableWidget->setItem(currentRow,0,new QTableWidgetItem("")); ui->tableWidget->setItem(currentRow,1,new QTableWidgetItem("")); path = OpenedFile->path(); } ui->tableWidget_2->resizeColumnToContents(0); ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->rowCount(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->setFocus(); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } }
void MainWindow::addFiles3() { QStringList mediaFiles; mediaFiles = QFileDialog::getOpenFileNames(this,"Load Audio Files", path, QString("Wave Files (*.wav)")); foreach(QString mediaFile,mediaFiles) { preFile = new QFile(mediaFile,this); preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); Array.append(preFile); const int currentRow = ui->tableWidget_3->rowCount(); ui->tableWidget_3->setRowCount(currentRow + 1); ui->tableWidget_3->setItem(currentRow,0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget_3->setItem(currentRow,1,new QTableWidgetItem("100")); path = OpenedFile->path(); } ui->tableWidget_3->resizeColumnToContents(0); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } }
void MainWindow::replaceFile() { QString mediaFile; mediaFile = QFileDialog::getOpenFileName(this,"LoadAudioFile",path,QString("Wave File (*.wav)")); if(mediaFile.isNull() == false) { path = QFileInfo(mediaFile).path(); preFile = new QFile(mediaFile,this); preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); WavFile *wFile = new WavFile(this); wFile->open(preFile->fileName()); qint64 realsize = OpenedFile->size() - wFile->headerLength(); qint64 totalduration = (realsize / (wFile->fileFormat().sampleRate() * wFile->fileFormat().channelCount() * wFile->fileFormat().sampleSize() / 8)); int nMinutes = (totalduration / 60) % 60; int nSeconds = (totalduration) % 60; QTime tTime(0,nMinutes,nSeconds,0); Array.append(preFile); wFile->close(); delete wFile; ui->tableWidget->setItem(ui->tableWidget->currentRow(),0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget->setItem(ui->tableWidget->currentRow(),1,new QTableWidgetItem("100")); ui->tableWidget->setItem(ui->tableWidget->currentRow(),2,new QTableWidgetItem(tTime.toString("mm:ss"))); ui->tableWidget->resizeColumnToContents(0); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } } else { return; } }
void MainWindow::replaceFile2() { QString mediaFile; mediaFile = QFileDialog::getOpenFileName(this,"LoadAudioFile",path,QString("Wave File (*.wav)")); if(mediaFile.isNull() == false) { path = QFileInfo(mediaFile).path(); preFile = new QFile(mediaFile,this); preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); WavFile *wFile = new WavFile(this); wFile->open(preFile->fileName()); qint64 realsize = OpenedFile->size() - wFile->headerLength(); qint64 totalduration = (realsize / (wFile->fileFormat().sampleRate() * wFile->fileFormat().channelCount() * wFile->fileFormat().sampleSize() / 8)); int nMinutes = (totalduration / 60) % 60; int nSeconds = (totalduration) % 60; QTime tTime(0,nMinutes,nSeconds,0); Array.append(preFile); wFile->close(); delete wFile; ui->tableWidget_2->setItem(ui->tableWidget_2->currentRow(),0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget_2->setItem(ui->tableWidget_2->currentRow(),1,new QTableWidgetItem("100")); ui->tableWidget_2->setItem(ui->tableWidget_2->currentRow(),2,new QTableWidgetItem(tTime.toString("mm:ss"))); ui->tableWidget_2->resizeColumnToContents(0); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } } else { return; } }
void MainWindow::replaceFile3() { QString mediaFile; mediaFile = QFileDialog::getOpenFileName(this,"LoadAudioFile",path,QString("Wave File (*.wav)")); if(mediaFile.isNull() == false) { path = QFileInfo(mediaFile).path(); preFile = new QFile(mediaFile,this); preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); Array.append(preFile); ui->tableWidget_3->setItem(ui->tableWidget_3->currentRow(),0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget_3->setItem(ui->tableWidget_3->currentRow(),1,new QTableWidgetItem("100")); ui->tableWidget_3->resizeColumnsToContents(); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } } else { return; } }
void MainWindow::addRow() { ui->tableWidget->insertRow(ui->tableWidget->currentRow()+1); ui->tableWidget->setItem(ui->tableWidget->currentRow()+1,0,new QTableWidgetItem("")); ui->tableWidget->setItem(ui->tableWidget->currentRow()+1,1,new QTableWidgetItem("")); ui->tableWidget_2->insertRow(ui->tableWidget->currentRow()+1); ui->tableWidget_2->setItem(ui->tableWidget->currentRow()+1,0,new QTableWidgetItem("")); ui->tableWidget_2->setItem(ui->tableWidget->currentRow()+1,1,new QTableWidgetItem("")); }
void MainWindow::addRow2() { ui->tableWidget_2->insertRow(ui->tableWidget_2->currentRow()+1); ui->tableWidget_2->setItem(ui->tableWidget_2->currentRow()+1,0,new QTableWidgetItem("")); ui->tableWidget_2->setItem(ui->tableWidget_2->currentRow()+1,1,new QTableWidgetItem("")); ui->tableWidget->insertRow(ui->tableWidget_2->currentRow()+1); ui->tableWidget->setItem(ui->tableWidget_2->currentRow()+1,0,new QTableWidgetItem("")); ui->tableWidget->setItem(ui->tableWidget_2->currentRow()+1,1,new QTableWidgetItem("")); }
void MainWindow::itemRemove() { ui->tableWidget_2->removeRow(ui->tableWidget->currentRow()); ui->tableWidget->removeRow(ui->tableWidget->currentRow()); }
void MainWindow::itemRemove2() { ui->tableWidget->removeRow(ui->tableWidget_2->currentRow()); ui->tableWidget_2->removeRow(ui->tableWidget_2->currentRow()); }
void MainWindow::itemRemove3() { ui->tableWidget_3->removeRow(ui->tableWidget_3->currentRow()); }
void MainWindow::itemClear() { for(int i = 0; i < Array.size();++i) { Array.at(i)->close(); } Array.clear(); for(int x = ui->tableWidget->rowCount()-1; x >= 0; x--) { ui->tableWidget->removeRow(x); } for(int x = ui->tableWidget_2->rowCount()-1; x >= 0; x--) { ui->tableWidget_2->removeRow(x); } for(int x = ui->tableWidget_3->rowCount()-1; x >= 0; x--) { ui->tableWidget_3->removeRow(x); } }
void MainWindow::itemClear3() { for(int x = ui->tableWidget_3->rowCount()-1; x >= 0; x--) { ui->tableWidget_3->removeRow(x); } }
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 14:54
mainwindow.cpp третья часть: void MainWindow::openPlaylist() { QString filePath = QFileDialog::getOpenFileName(this,"Load Playlist", path,QString("List Files (*.lst)")); loadList(filePath); }
void MainWindow::loadList(QString fileName) { itemClear(); if(fileName.isNull() == false) { path = QFileInfo(fileName).path(); QFile file(fileName); file.open(QFile::ReadOnly | QFile::Text); QTextStream textStream(&file); QStringList lines; QString MediaFile, MediaFile2; while(true) { QString line = textStream.readLine(); lines = line.split(";"); if(line.isNull()) { break; } else { MediaFile = lines.value(0); MediaFile2 = lines.value(2); const int currentRow = ui->tableWidget->rowCount(); ui->tableWidget->setRowCount(currentRow + 1); ui->tableWidget_2->setRowCount(currentRow + 1); if(MediaFile.isEmpty() == false) { preFile = new QFile(MediaFile,this); if(preFile->exists() == true) { preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); WavFile *wFile = new WavFile(this); wFile->open(preFile->fileName()); qint64 realsize = OpenedFile->size() - wFile->headerLength(); qint64 totalduration = (realsize / (wFile->fileFormat().sampleRate() * wFile->fileFormat().channelCount() * wFile->fileFormat().sampleSize() / 8)); int nMinutes = (totalduration / 60) % 60; int nSeconds = (totalduration) % 60; QTime tTime(0,nMinutes,nSeconds,0); Array.append(preFile); wFile->close(); delete wFile; ui->tableWidget->setItem(currentRow,0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget->setItem(currentRow,1,new QTableWidgetItem(lines.value(1))); ui->tableWidget->setItem(currentRow,2,new QTableWidgetItem(tTime.toString("mm:ss"))); ui->tableWidget_2->setItem(currentRow,0,new QTableWidgetItem(lines.value(2))); ui->tableWidget_2->setItem(currentRow,1,new QTableWidgetItem(lines.value(3))); } else { ui->tableWidget->setItem(currentRow,0,new QTableWidgetItem("THERE'S NO SUCH FILE!!!")); ui->tableWidget->setItem(currentRow,1,new QTableWidgetItem(lines.value(1))); ui->tableWidget_2->setItem(currentRow,0,new QTableWidgetItem(lines.value(2))); ui->tableWidget_2->setItem(currentRow,1,new QTableWidgetItem(lines.value(3))); } } else if(MediaFile2.isEmpty() == false) { preFile2 = new QFile(MediaFile2,this); if(preFile2->exists() == true) { preFile2->open(QIODevice::ReadOnly); OpenedFile2 = new QFileInfo(preFile2->fileName()); WavFile *wFile2 = new WavFile(this); wFile2->open(preFile2->fileName()); qint64 realsize2 = OpenedFile2->size() - wFile2->headerLength(); qint64 totalduration2 = (realsize2 / (wFile2->fileFormat().sampleRate() * wFile2->fileFormat().channelCount() * wFile2->fileFormat().sampleSize() / 8)); int nMinutes2 = (totalduration2 / 60) % 60; int nSeconds2 = (totalduration2) % 60; QTime tTime2(0,nMinutes2,nSeconds2,0); Array.append(preFile2); wFile2->close(); delete wFile2; ui->tableWidget->setItem(currentRow,0,new QTableWidgetItem(lines.value(0))); ui->tableWidget->setItem(currentRow,1,new QTableWidgetItem(lines.value(1))); ui->tableWidget_2->setItem(currentRow,0,new QTableWidgetItem(OpenedFile2->baseName())); ui->tableWidget_2->setItem(currentRow,1,new QTableWidgetItem(lines.value(3))); ui->tableWidget_2->setItem(currentRow,2,new QTableWidgetItem(tTime2.toString("mm:ss"))); } else { ui->tableWidget->setItem(currentRow,0,new QTableWidgetItem(lines.value(0))); ui->tableWidget->setItem(currentRow,1,new QTableWidgetItem(lines.value(1))); ui->tableWidget_2->setItem(currentRow,0,new QTableWidgetItem("THERE'S NO SUCH FILE!!!")); ui->tableWidget_2->setItem(currentRow,1,new QTableWidgetItem(lines.value(3))); } } } } ui->tableWidget->resizeColumnToContents(0); ui->tableWidget_2->resizeColumnToContents(0); ui->tableWidget->setCurrentCell(0,0,QItemSelectionModel::SelectCurrent); ui->tableWidget->setFocus(); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } } else { return; } } void MainWindow::loadList2() { itemClear3(); QString fileName = QFileDialog::getOpenFileName(this,"Load Playlist", path,QString("List Files (*.lst)")); if(fileName.isNull() == false) { path = QFileInfo(fileName).path(); QFile file(fileName); file.open(QFile::ReadOnly | QFile::Text); QTextStream textStream(&file); QStringList lines; while(true) { QString line = textStream.readLine(); lines = line.split(";"); QString MediaFile; if(line.isNull()) { break; } else { const int currentRow = ui->tableWidget_3->rowCount(); ui->tableWidget_3->setRowCount(currentRow + 1); MediaFile = lines.value(0); if(MediaFile.isEmpty() != true) { preFile = new QFile(MediaFile,this); if(preFile->exists() == true) { preFile->open(QIODevice::ReadOnly); OpenedFile = new QFileInfo(preFile->fileName()); Array.append(preFile); ui->tableWidget_3->setItem(currentRow,0,new QTableWidgetItem(OpenedFile->baseName())); ui->tableWidget_3->setItem(currentRow,1,new QTableWidgetItem(lines.value(1))); } else { ui->tableWidget_3->setItem(currentRow,0,new QTableWidgetItem("THERE'S NO SUCH FILE!!!")); ui->tableWidget_3->setItem(currentRow,1,new QTableWidgetItem(lines.value(1))); } } } } ui->tableWidget_3->resizeColumnToContents(0); for(int i = 0;i < Array.size();++i) { for(int j = i +1;j < Array.size(); ++j) { if(Array[i]==Array[j]) { Array.remove(i); } } } } else { return; } }
void MainWindow::saveList() { QString fileName = QFileDialog::getSaveFileName(this,"Save Playlist", path, QString("List File (*.lst)")); QFile file(fileName); file.open(QFile::WriteOnly | QFile::Text); QTextStream out(&file); for(int i = 0; i < ui->tableWidget->rowCount(); ++i) { for(int j = 0; j < Array.size(); ++j) { outputFile.setFile(Array.at(j)->fileName()); if(ui->tableWidget->item(i,0)->text() == outputFile.baseName()) { out<<Array.at(j)->fileName()<<";"<<ui->tableWidget->item(i,1)->text()<<";"<<";"<<endl; } else if(ui->tableWidget_2->item(i,0)->text() == outputFile.baseName()) { out<<";"<<";"<<Array.at(j)->fileName()<<";"<<ui->tableWidget_2->item(i,1)->text()<<endl; } } } file.close(); path = QFileInfo(fileName).path(); ui->tableWidget->setFocus(); }
void MainWindow::saveList2() { QString fileName = QFileDialog::getSaveFileName(this,"Save Playlist", path, QString("List File (*.lst)")); QFile file(fileName); file.open(QFile::WriteOnly | QFile::Text); QTextStream out(&file); for(int i = 0; i < ui->tableWidget_3->rowCount(); ++i) { for(int j = 0;j < Array.size();++j) { outputFile.setFile(Array.at(j)->fileName()); if(ui->tableWidget_3->item(i,0)->text() == outputFile.baseName()) { out<<Array.at(j)->fileName()<<";"<<ui->tableWidget_3->item(i,1)->text()<<endl; } } } file.close(); path = QFileInfo(fileName).path(); }
void MainWindow::itemPlay() { if(ui->tableWidget->rowCount() == 0) { ui->label->setText(errorMessage1); } else { if(ui->tableWidget->currentItem()->text().isEmpty()) { ui->label->setText(errorMessage); } else { if(q_audio->state() == QAudio::ActiveState) itemStop(); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile.setFile(Array.at(i)->fileName()); if(inputFile.baseName() == ui->tableWidget->item(ui->tableWidget->currentRow(),0)->text()) nowPlayingFile = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile->fileName()); nowPlayingFile->seek(wav->headerLength()); q_format = wav->fileFormat(); delete q_audio; q_audio = 0; q_audio = new QAudioOutput(q_device,q_format,this); inputFile.setFile(nowPlayingFile->fileName()); if(ui->tableWidget->item(ui->tableWidget->currentRow(),1)->text().isEmpty()) { q_audio->setVolume(1.0); } else { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume = ui->tableWidget->currentItem()->text().toInt(); q_audio->setVolume(Volume / 100); } q_audio->start(nowPlayingFile); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget->scrollToItem(ui->tableWidget->currentItem(),QAbstractItemView::PositionAtTop); ui->tableWidget_2->scrollToItem(ui->tableWidget_2->item(ui->tableWidget->currentRow(),0),QAbstractItemView::PositionAtTop); qint64 size = nowPlayingFile->size() - wav->headerLength(); qint64 duration = (size / (q_format.sampleRate() * q_format.channelCount() * q_format.sampleSize() / 8)); ui->seekSlider->setMaximum(duration * 1000); infoThread->start(); int totalminutes = (duration / 60) % 60; int totalseconds = (duration) % 60; QString qname = inputFile.baseName(); QTime totaltime(0, totalminutes, totalseconds, 0); ui->label->setText(qname); ui->totalTimeDisp->display(totaltime.toString("mm:ss")); wav->close(); delete wav; for(int x=0;x<ui->tableWidget->rowCount();x++) { ui->tableWidget->item(x,0)->setBackgroundColor(QColor::fromRgb(213, 213, 160, 255)); } ui->tableWidget->item(ui->tableWidget->currentRow(),0)->setBackgroundColor(Qt::lightGray); if(ui->tableWidget->currentRow() == ui->tableWidget->rowCount() - 1) { return; } else { if(ui->tableWidget->item(ui->tableWidget->currentRow()+1,0)->text().isEmpty()) { ui->tableWidget_2->setFocus(); ui->tableWidget_2->setCurrentCell(ui->tableWidget->currentRow()+1,0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->setFocus(); autocross = true; } else { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow() + 1,0,QItemSelectionModel::SelectCurrent); ui->tableWidget->setFocus(); autocross = false; } } } } }
void MainWindow::itemPlay2() { if(ui->tableWidget_2->rowCount() == 0) { ui->label_2->setText(errorMessage1); } else { if(ui->tableWidget_2->currentItem()->text().isEmpty()) { ui->label_2->setText(errorMessage); } else { if(q_audio2->state() == QAudio::ActiveState) itemStop2(); ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile2.setFile(Array.at(i)->fileName()); if(inputFile2.baseName() == ui->tableWidget_2->item(ui->tableWidget_2->currentRow(),0)->text()) nowPlayingFile2 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile2->fileName()); nowPlayingFile2->seek(wav->headerLength()); q_format2 = wav->fileFormat(); delete q_audio2; q_audio2 = 0; q_audio2 = new QAudioOutput(q_device2,q_format2,this); inputFile2.setFile(nowPlayingFile2->fileName()); if(ui->tableWidget_2->item(ui->tableWidget_2->currentRow(),1)->text().isEmpty()) { q_audio2->setVolume(1.0); } else { ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume2 = ui->tableWidget_2->currentItem()->text().toInt(); q_audio2->setVolume(Volume2 / 100); } q_audio2->start(nowPlayingFile2); ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->scrollToItem(ui->tableWidget_2->currentItem(),QAbstractItemView::PositionAtTop); ui->tableWidget->scrollToItem(ui->tableWidget->item(ui->tableWidget_2->currentRow(),0),QAbstractItemView::PositionAtTop); infoThread2->start(); qint64 size2 = nowPlayingFile2->size() - wav->headerLength(); qint64 duration2 = (size2 / (q_format2.sampleRate() * q_format2.channelCount() * q_format2.sampleSize() / 8)); ui->seekSlider_2->setMaximum(duration2 * 1000); int totalminutes2 = (duration2 / 60) % 60; int totalseconds2 = (duration2) % 60; QString qname2 = inputFile2.baseName(); QTime totaltime2(0, totalminutes2, totalseconds2, 0); ui->label_2->setText(qname2); ui->totalTimeDisp_2->display(totaltime2.toString("mm:ss")); wav->close(); delete wav; for(int x=0;x<ui->tableWidget_2->rowCount();x++) { ui->tableWidget_2->item(x,0)->setBackgroundColor(QColor::fromRgb(213, 213, 160, 255)); } ui->tableWidget_2->item(ui->tableWidget_2->currentRow(),0)->setBackgroundColor(Qt::lightGray); if(ui->tableWidget_2->currentRow() == ui->tableWidget_2->rowCount() - 1) { return; } else { if(ui->tableWidget_2->item(ui->tableWidget_2->currentRow()+1,0)->text().isEmpty()) { ui->tableWidget->setFocus(); ui->tableWidget->setCurrentCell(ui->tableWidget_2->currentRow()+1,0,QItemSelectionModel::SelectCurrent); ui->tableWidget->setFocus(); autocross2 = true; } else { ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow() + 1,0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->setFocus(); autocross2 = false; } } } } }
void MainWindow::seekF() { nowPlayingFile->seek(nowPlayingFile->pos() + 100000); }
void MainWindow::seekF2() { nowPlayingFile2->seek(nowPlayingFile2->pos() + 100000); }
void MainWindow::seekB() { nowPlayingFile->seek(nowPlayingFile->pos() - 100000); }
void MainWindow::seekB2() { nowPlayingFile2->seek(nowPlayingFile2->pos() - 100000); }
void MainWindow::fadeOut() { qreal currentVolume = q_audio->volume(); if(currentVolume > 0.01) { q_audio->setVolume(currentVolume - 0.01); } else { emit StopFadeOut(); itemStop(); } }
void MainWindow::fadeOut2() { qreal currentVolume2 = q_audio2->volume(); if(currentVolume2 > 0.01) { q_audio2->setVolume(currentVolume2 - 0.01); } else { emit StopFadeOut2(); itemStop2(); } }
void MainWindow::fade() { qreal currentVolume = q_audio->volume(); float userVolume = ui->volumeEdit->text().toFloat() / 100; if(currentVolume != userVolume) { if(currentVolume > userVolume) { q_audio->setVolume(currentVolume - 0.01); } if(currentVolume < userVolume) { q_audio->setVolume(currentVolume + 0.01); } } else { emit StopFadeSignal(); } }
void MainWindow::fade2() { qreal currentVolume2 = q_audio2->volume(); float userVolume2 = ui->volumeEdit_2->text().toFloat() / 100; if(currentVolume2 != userVolume2) { if(currentVolume2 > userVolume2) { q_audio2->setVolume(currentVolume2 - 0.01); } if(currentVolume2 < userVolume2) { q_audio2->setVolume(currentVolume2 + 0.01); } } else { emit StopFadeSignal2(); } }
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 14:55
mainwindow.cpp последняя часть: void MainWindow::fadeIn() { ui->tableWidget->setItem(ui->tableWidget->currentRow(),1,new QTableWidgetItem("0")); ui->volumeEdit->clear(); ui->volumeEdit->setText("100"); itemPlay(); fadeTimer->start();
}
void MainWindow::fadeIn2() { ui->tableWidget_2->setItem(ui->tableWidget_2->currentRow(),1,new QTableWidgetItem("0")); ui->volumeEdit_2->clear(); ui->volumeEdit_2->setText("100"); itemPlay2(); fadeTimer2->start(); }
void MainWindow::crossFade() { fadeOutTimer->start(); fadeIn2(); }
void MainWindow::crossFade2() { fadeOutTimer2->start(); fadeIn(); }
void MainWindow::itemPause(){q_audio->suspend();}
void MainWindow::itemPause2(){q_audio2->suspend();}
void MainWindow::itemUnPause(){q_audio->resume();}
void MainWindow::itemUnPause2(){q_audio2->resume();}
void MainWindow::itemStop() { infoThread->exit(); ui->lcdNumber->display("00:00"); ui->totalTimeDisp->display("00:00"); ui->label->clear(); ui->seekSlider->setSliderPosition(0); q_audio->stop(); fadeTimer->stop(); fadeOutTimer->stop(); autocross = false; }
void MainWindow::itemStop2() { infoThread2->exit(); ui->lcdNumber_2->display("00:00"); ui->totalTimeDisp_2->display("00:00"); ui->label_2->clear(); ui->seekSlider_2->setSliderPosition(0); q_audio2->stop(); fadeTimer2->stop(); fadeOutTimer2->stop(); autocross2 = false; }
void MainWindow::itemStop3() { infoThread3->exit(); q_audio3->stop(); }
void MainWindow::f1() { if(ui->tableWidget_3->rowCount() == 0) { return; } else { if(q_audio3->state() == QAudio::ActiveState) itemStop3(); ui->tableWidget_3->setCurrentCell(0,0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile3.setFile(Array.at(i)->fileName()); if(inputFile3.baseName() == ui->tableWidget_3->item(ui->tableWidget_3->currentRow(),0)->text()) nowPlayingFile3 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile3->fileName()); nowPlayingFile3->seek(wav->headerLength()); delete q_audio3; q_audio3 = 0; q_audio3 = new QAudioOutput(q_device3,wav->fileFormat(),this); wav->close(); delete wav; ui->tableWidget_3->setCurrentCell(ui->tableWidget_3->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume3 = ui->tableWidget_3->currentItem()->text().toInt(); q_audio3->setVolume(Volume3 / 100); q_audio3->start(nowPlayingFile3); } }
void MainWindow::f2() { if(ui->tableWidget_3->rowCount() == 0) { return; } else { if(q_audio3->state() == QAudio::ActiveState) itemStop3(); ui->tableWidget_3->setCurrentCell(1,0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile3.setFile(Array.at(i)->fileName()); if(inputFile3.baseName() == ui->tableWidget_3->item(ui->tableWidget_3->currentRow(),0)->text()) nowPlayingFile3 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile3->fileName()); nowPlayingFile3->seek(wav->headerLength()); delete q_audio3; q_audio3 = 0; q_audio3 = new QAudioOutput(q_device3,wav->fileFormat(),this); wav->close(); delete wav; ui->tableWidget_3->setCurrentCell(ui->tableWidget_3->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume3 = ui->tableWidget_3->currentItem()->text().toInt(); q_audio3->setVolume(Volume3 / 100); q_audio3->start(nowPlayingFile3); } }
void MainWindow::f3() { if(ui->tableWidget_3->rowCount() == 0) { return; } else { if(q_audio3->state() == QAudio::ActiveState) itemStop3(); ui->tableWidget_3->setCurrentCell(2,0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile3.setFile(Array.at(i)->fileName()); if(inputFile3.baseName() == ui->tableWidget_3->item(ui->tableWidget_3->currentRow(),0)->text()) nowPlayingFile3 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile3->fileName()); nowPlayingFile3->seek(wav->headerLength()); delete q_audio3; q_audio3 = 0; q_audio3 = new QAudioOutput(q_device3,wav->fileFormat(),this); wav->close(); delete wav; ui->tableWidget_3->setCurrentCell(ui->tableWidget_3->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume3 = ui->tableWidget_3->currentItem()->text().toInt(); q_audio3->setVolume(Volume3 / 100); q_audio3->start(nowPlayingFile3); } }
void MainWindow::f4() { if(ui->tableWidget_3->rowCount() == 0) { return; } else { if(q_audio3->state() == QAudio::ActiveState) itemStop3(); ui->tableWidget_3->setCurrentCell(3,0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile3.setFile(Array.at(i)->fileName()); if(inputFile3.baseName() == ui->tableWidget_3->item(ui->tableWidget_3->currentRow(),0)->text()) nowPlayingFile3 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile3->fileName()); nowPlayingFile3->seek(wav->headerLength()); delete q_audio3; q_audio3 = 0; q_audio3 = new QAudioOutput(q_device3,wav->fileFormat(),this); wav->close(); delete wav; ui->tableWidget_3->setCurrentCell(ui->tableWidget_3->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume3 = ui->tableWidget_3->currentItem()->text().toInt(); q_audio3->setVolume(Volume3 / 100); q_audio3->start(nowPlayingFile3); } }
void MainWindow::f5() { if(ui->tableWidget_3->rowCount() == 0) { return; } else { if(q_audio3->state() == QAudio::ActiveState) itemStop3(); ui->tableWidget_3->setCurrentCell(4,0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile3.setFile(Array.at(i)->fileName()); if(inputFile3.baseName() == ui->tableWidget_3->item(ui->tableWidget_3->currentRow(),0)->text()) nowPlayingFile3 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile3->fileName()); nowPlayingFile3->seek(wav->headerLength()); delete q_audio3; q_audio3 = 0; q_audio3 = new QAudioOutput(q_device3,wav->fileFormat(),this); wav->close(); delete wav; ui->tableWidget_3->setCurrentCell(ui->tableWidget_3->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume3 = ui->tableWidget_3->currentItem()->text().toInt(); q_audio3->setVolume(Volume3 / 100); q_audio3->start(nowPlayingFile3); } }
void MainWindow::f6() { if(ui->tableWidget_3->rowCount() == 0) { return; } else { if(q_audio3->state() == QAudio::ActiveState) itemStop3(); ui->tableWidget_3->setCurrentCell(5,0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile3.setFile(Array.at(i)->fileName()); if(inputFile3.baseName() == ui->tableWidget_3->item(ui->tableWidget_3->currentRow(),0)->text()) nowPlayingFile3 = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile3->fileName()); nowPlayingFile3->seek(wav->headerLength()); delete q_audio3; q_audio3 = 0; q_audio3 = new QAudioOutput(q_device3,wav->fileFormat(),this); wav->close(); delete wav; ui->tableWidget_3->setCurrentCell(ui->tableWidget_3->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume3 = ui->tableWidget_3->currentItem()->text().toInt(); q_audio3->setVolume(Volume3 / 100); q_audio3->start(nowPlayingFile3); } }
void MainWindow::keyReleaseEvent(QKeyEvent *event) { switch(event->key()) { case Qt::Key_Asterisk: case Qt::Key_F10: itemStop(); break; case Qt::Key_Minus: case Qt::Key_F11: itemStop2(); break; case Qt::Key_Slash: case Qt::Key_F12: itemStop3(); break; case Qt::Key_F8: showFullScreen(); break; case Qt::Key_F9: showNormal(); break; case Qt::Key_F1: case Qt::Key_1: f1(); break; case Qt::Key_F2: case Qt::Key_2: f2(); break; case Qt::Key_F3: case Qt::Key_3: f3(); break; case Qt::Key_F4: case Qt::Key_4: f4(); break; case Qt::Key_F5: case Qt::Key_5: f5(); break; case Qt::Key_F6: case Qt::Key_6: f6(); break; case Qt::Key_Enter: case Qt::Key_Return: if(ui->tableWidget->hasFocus()) { itemPlay(); } else { itemPlay2(); } break; case Qt::Key_Delete: if(ui->tableWidget->hasFocus()) { ui->tableWidget->currentItem()->setText(""); if(ui->tableWidget->currentColumn() == 0) { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),1,QItemSelectionModel::SelectCurrent); ui->tableWidget->currentItem()->setText(""); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),2,QItemSelectionModel::SelectCurrent); ui->tableWidget->currentItem()->setText(""); } else if(ui->tableWidget->currentColumn() == 1) { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget->currentItem()->setText(""); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),2,QItemSelectionModel::SelectCurrent); ui->tableWidget->currentItem()->setText(""); } else { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget->currentItem()->setText(""); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),1,QItemSelectionModel::SelectCurrent); ui->tableWidget->currentItem()->setText(""); } } else if(ui->tableWidget_2->hasFocus()) { ui->tableWidget_2->currentItem()->setText(""); if(ui->tableWidget_2->currentColumn() == 0) { ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),1,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->currentItem()->setText(""); ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),2,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->currentItem()->setText(""); } else if(ui->tableWidget_2->currentColumn() == 1) { ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->currentItem()->setText(""); ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),2,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->currentItem()->setText(""); } else { ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->currentItem()->setText(""); ui->tableWidget_2->setCurrentCell(ui->tableWidget_2->currentRow(),1,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->currentItem()->setText(""); } } else { itemRemove3(); } break; default: QWidget::keyReleaseEvent(event); } }
void MainWindow::updatePos() { qint64 position = nowPlayingFile->pos(); qint64 postime = (position / (q_format.sampleRate() * q_format.channelCount() * q_format.sampleSize() / 8)); int minutes = (postime / 60) % 60; int seconds = (postime) % 60; QTime time(0, minutes, seconds, 0); ui->lcdNumber->display(time.toString("mm:ss")); ui->seekSlider->setSliderPosition(postime * 1000); ui->volumeDisp->display(q_audio->volume() * 100); int nowVolume = q_audio->volume() * 100; ui->dial->setSliderPosition(nowVolume); if(ui->volumeEdit->text().toInt() == ui->dial->sliderPosition()) fadeTimer->stop(); if(nowPlayingFile->atEnd()) { if(ui->checkBox->isChecked() == false) itemStop(); else { if(autocross == true) { itemStop(); itemPlay2(); } else itemStop(); } } }
void MainWindow::updatePos2() { qint64 position2 = nowPlayingFile2->pos(); qint64 postime2 = (position2 / (q_format2.sampleRate() * q_format2.channelCount() * q_format2.sampleSize() / 8)); int minutes2 = (postime2 / 60) % 60; int seconds2 = (postime2) % 60; QTime time2(0, minutes2, seconds2, 0); ui->lcdNumber_2->display(time2.toString("mm:ss")); ui->seekSlider_2->setSliderPosition(postime2 * 1000); ui->volumeDisp_2->display(q_audio2->volume() * 100); int nowVolume2 = q_audio2->volume() * 100; ui->dial_2->setSliderPosition(nowVolume2); if(ui->volumeEdit_2->text().toInt() == ui->dial_2->sliderPosition()) fadeTimer2->stop(); if(nowPlayingFile2->atEnd()) { if(ui->checkBox->isChecked() == false) itemStop2(); else { if(autocross2 == true) { itemStop2(); itemPlay(); } else itemStop2(); } } }
void MainWindow::updatePos3() { if(nowPlayingFile3->atEnd()) itemStop3(); }
void MainWindow::setPos() { int switchedPos = ui->seekSlider->sliderPosition(); qint64 filePos = (switchedPos / 1000) * (q_format.sampleRate() * q_format.channelCount() * q_format.sampleSize() / 8); nowPlayingFile->seek(filePos); ui->tableWidget->setFocus(); }
void MainWindow::setPos2() { int switchedPos2 = ui->seekSlider_2->sliderPosition(); qint64 filePos2 = (switchedPos2 / 1000) * (q_format2.sampleRate() * q_format2.channelCount() * q_format2.sampleSize() / 8); nowPlayingFile2->seek(filePos2); ui->tableWidget_2->setFocus(); }
void MainWindow::setVolume() { float switchedVolume = ui->dial->sliderPosition(); qreal targetVolume = switchedVolume / 100; q_audio->setVolume(targetVolume); ui->tableWidget->setFocus(); }
void MainWindow::setVolume2() { float switchedVolume2 = ui->dial->sliderPosition(); qreal targetVolume2 = switchedVolume2 / 100; q_audio2->setVolume(targetVolume2); ui->tableWidget_2->setFocus(); }
void MainWindow::aboutToClose() { d->exec(); }
void MainWindow::closeEvent(QCloseEvent *event) { aboutToClose(); event->ignore(); }
MainWindow::~MainWindow() { delete ui; }
Название: Re: проблема с QAudioOutput
Отправлено: Bepec от Сентябрь 28, 2014, 15:03
Мог только H выложить - сразу понятно, что архитектура хромает :D Ужас.
PS по звуку не работал, советов дать не могу :)
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 15:14
+ ко всему в проект входят позаимствованные wavfile.h wavfile.cpp utils.h utils.cpp использующиеся в качестве парсера, иначе возникают проблемы со щелчками и несовпадениями форматов. Также делегат запрещающий редактировать некоторые ячейки, ну и диалог выхода из программы, предотвращающий её случайное закрытие. Вот пока и всё.
В общем-то это не профессиональная работа, так-как я не программист а звукорежиссёр, просто возникла острая потребность в подобной программе, таких продуктов на рынке почти нет, а те которые есть не устраивают либо отсутствием необходимого функционала, либо абсолютной нестабильностью в работе. Я понимаю, что половину того что я написал, можно было реализовать через классы, сигналы и прочие прелести ООП, да и в общем-то облагородить внешний вид кода, но времени не хватает. Тот код, который получилось сделать долгим путём проб и ошибок, полностью рабочий, функционал стабилен, и не вызывает критических ошибок, по крайней мере этот вариант программы уже тестировался на спектаклях. Вот, собственно, в результате тестирования и выяснилось, что когда останавливаешь трек на одной аудиокарте, на другой происходит микрозаминка, как будто плохо склеили трек.
Так что не судите строго за код (если будут советы по его упрощению/улучшению, советуйте) - просто помогите разобраться с причиной артефакта, посоветуйте в какую сторону копать.
Название: Re: проблема с QAudioOutput
Отправлено: Bepec от Сентябрь 28, 2014, 15:48
Тогда прошу уточнения - какие ф-ции при запуске/остановке вызываются? :) копать код нет желания :)
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 16:46
Перед запуском wav-файл парсится, создаётся QAudioOutput с заданием формата (взятого из хедера wav), устройства на которое будет послан звук. Собственно, для запуска трека используется метод QAudioOutput::start(QIODevice *device) в качестве QIODevice используется объект класса QFile, чтение начинается с позиции аудиоданных, хедер пропускается. Для остановки используется метод QAudioOutput::stop(). При вызове именно этого метода, на параллельно запущенном QAudioOutput возникает заминка. Здесь привожу пример из моего кода: void MainWindow::itemPlay() { if(ui->tableWidget->rowCount() == 0) { ui->label->setText(errorMessage1); } else { if(ui->tableWidget->currentItem()->text().isEmpty()) { ui->label->setText(errorMessage); } else { if(q_audio->state() == QAudio::ActiveState) itemStop(); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),0,QItemSelectionModel::SelectCurrent); for(int i = 0;i < Array.size();++i) { inputFile.setFile(Array.at(i)->fileName()); if(inputFile.baseName() == ui->tableWidget->item(ui->tableWidget->currentRow(),0)->text()) nowPlayingFile = Array.at(i); } WavFile *wav = new WavFile(this); wav->open(nowPlayingFile->fileName()); nowPlayingFile->seek(wav->headerLength()); q_format = wav->fileFormat(); delete q_audio; q_audio = 0; q_audio = new QAudioOutput(q_device,q_format,this); inputFile.setFile(nowPlayingFile->fileName()); if(ui->tableWidget->item(ui->tableWidget->currentRow(),1)->text().isEmpty()) { q_audio->setVolume(1.0); } else { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),1,QItemSelectionModel::SelectCurrent); Volume = ui->tableWidget->currentItem()->text().toInt(); q_audio->setVolume(Volume / 100); } q_audio->start(nowPlayingFile); ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow(),0,QItemSelectionModel::SelectCurrent); ui->tableWidget->scrollToItem(ui->tableWidget->currentItem(),QAbstractItemView::PositionAtTop); ui->tableWidget_2->scrollToItem(ui->tableWidget_2->item(ui->tableWidget->currentRow(),0),QAbstractItemView::PositionAtTop); qint64 size = nowPlayingFile->size() - wav->headerLength(); qint64 duration = (size / (q_format.sampleRate() * q_format.channelCount() * q_format.sampleSize() / 8)); ui->seekSlider->setMaximum(duration * 1000); infoThread->start(); int totalminutes = (duration / 60) % 60; int totalseconds = (duration) % 60; QString qname = inputFile.baseName(); QTime totaltime(0, totalminutes, totalseconds, 0); ui->label->setText(qname); ui->totalTimeDisp->display(totaltime.toString("mm:ss")); wav->close(); delete wav; for(int x=0;x<ui->tableWidget->rowCount();x++) { ui->tableWidget->item(x,0)->setBackgroundColor(QColor::fromRgb(213, 213, 160, 255)); } ui->tableWidget->item(ui->tableWidget->currentRow(),0)->setBackgroundColor(Qt::lightGray); if(ui->tableWidget->currentRow() == ui->tableWidget->rowCount() - 1) { return; } else { if(ui->tableWidget->item(ui->tableWidget->currentRow()+1,0)->text().isEmpty()) { ui->tableWidget_2->setFocus(); ui->tableWidget_2->setCurrentCell(ui->tableWidget->currentRow()+1,0,QItemSelectionModel::SelectCurrent); ui->tableWidget_2->setFocus(); autocross = true; } else { ui->tableWidget->setCurrentCell(ui->tableWidget->currentRow() + 1,0,QItemSelectionModel::SelectCurrent); ui->tableWidget->setFocus(); autocross = false; } } } } }
void MainWindow::itemStop() { infoThread->exit(); ui->lcdNumber->display("00:00"); ui->totalTimeDisp->display("00:00"); ui->label->clear(); ui->seekSlider->setSliderPosition(0); q_audio->stop(); fadeTimer->stop(); fadeOutTimer->stop(); autocross = false; }
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 16:51
Собственно, у этих двух функций есть двойники для второй деки плейера, работающей с другой аудиокартой. Переменные и объекты классов, используемые в функциях второй деки, естественно носят имя с приставкой "2". Каким образом они могут между собой пересекаться, если в памяти им присваиваются разные адреса?
Название: Re: проблема с QAudioOutput
Отправлено: Bepec от Сентябрь 28, 2014, 17:48
Ну есть вариант что вас тыркает из-за того, что всё происходит в одном потоке :)
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 18:15
Я вот так и подозреваю, но чтобы использовать QThread, нужно будет создать по классу (я так понял из документации) на каждую деку с реализацией функции проигрывания, чтобы потом объекты этих классов впихнуть каждый в свой thread. Создавать придётся потому что как я понял, объект класса QAudioOutput не запихивается в QThread, как-то пробовал. Вчера пробовал создать подобный класс, но увы, хоть и собирается, звука почему-то нет, при этом все аргументы по идее должны передаваться создаваемому объекту класса. Вот код: deck1.h #ifndef DECK1_H #define DECK1_H
#include <QObject> #include "wavfile.h" #include <QAudioOutput> #include <QAudioDeviceInfo> #include <QAudioFormat>
class Deck1 : public QObject { Q_OBJECT
public: Deck1(QFile *wavSource,QAudioDeviceInfo audioDevice,qreal startVolume); QAudioOutput *output;
private: QFile *source; WavFile *wav; QAudioFormat format; QAudioDeviceInfo device; qreal volume;
public slots: void play();
private slots: void parse(); void createAudioOutput(); void handleSignals(QAudio::State state);
signals: void finished(); };
#endif // DECK1_H
deck1.cpp #include "deck1.h"
Deck1::Deck1(QFile *wavSource,QAudioDeviceInfo audioDevice,qreal startVolume) { source = wavSource; wav = new WavFile(this); device = audioDevice; volume = startVolume; connect(output,SIGNAL(stateChanged(QAudio::State)),this,SLOT(handleSignals(QAudio::State state))); }
void Deck1::play() { parse(); createAudioOutput(); output->start(source); }
void Deck1::parse() { wav->open(source->fileName()); format = wav->fileFormat(); source->seek(wav->headerLength()); }
void Deck1::createAudioOutput() { output = new QAudioOutput(device,format,this); output->setVolume(volume); }
void Deck1::handleSignals(QAudio::State state) { switch (state) { case QAudio::IdleState: emit finished(); break; case QAudio::StoppedState: emit finished(); break; default: break; } }
Название: Re: проблема с QAudioOutput
Отправлено: xokc от Сентябрь 28, 2014, 20:15
Мой опыт работы с выводом звука через QAudioOutput был неудачным - то оно заикалось, то просто переставало звук выводить. После этого для работы со звуком пользуюсь portaudio (http://www.portaudio.com/) или rtaudio (http://www.music.mcgill.ca/~gary/rtaudio/) - там таких проблем не было.
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 20:35
Большое спасибо, не хотелось бы перестраиваться, но о QAudio действительно очень много негатива везде. Ссылки полезные, даже что-то про ASIO увидел. Вопрос такой, меня помимо воспроизведения интересуют функции автоматического управления громкостью, т.е. fadein, fadeout, crossfade. В QAudioOutput очень неудобно реализовано, поскольку метод отвечающий за громкость QAudioOutput::setVolume(qreal volume) обращается напрямую к драйверу звуковой карты, регулируя громкость виртуального микшера. Мне необходимо делать это внутри программы, не затрагивая системную громкость. Я не успею сейчас, конечно, прочитать документацию по приведённым вами ссылкам, если вы работали с этими библиотеками - вы наверняка знаете, как обстоит дело с контрольными функциями этих библиотек?
Документацию обязательно почитаю, попробую перевести свой проект на одну из этих библиотек, хотя бы, в качестве эксперимента. Спасибо.
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Сентябрь 28, 2014, 23:08
Кстати, успешно поместил каждый QAudioOutput в отдельный QThread, не помогло. Артефакт остался. Более того, посмотрел через отладчик - QAudioOutput::start(QIODevice *device) формирует собственный поток, но к сожалению, по какой-то причине, остановка этого, и любого другого потока влияет на аудиокарту, вызывая чёртов щелчок. Этот щелчок проявляется при вызовах stop, suspend, reset. И ещё: щелчкок пропадает, если вызван фейдаут, т.е., если громкость аудиовыхода 0, но только на том аудиовыходе, где убрана громкость. А на параллельно воспроизводящемся треке на другом аудиовыходе щелчёк остаётся. По-видимому, нельзя создавать более одного объекта QAudioOutput. Можно ли решить проблему унаследовавшись от данного класса? Бред, наврное...
Название: Re: проблема с QAudioOutput
Отправлено: xokc от Сентябрь 29, 2014, 08:31
Ссылки полезные, даже что-то про ASIO увидел.
Обе библиотеки умеют работать со звуком через ASIO, но для этого при их сборке нужно сделать соответствующие define и скачать ASIO SDK. меня помимо воспроизведения интересуют функции автоматического управления громкостью, т.е. fadein, fadeout, crossfade. В QAudioOutput очень неудобно реализовано, поскольку метод отвечающий за громкость QAudioOutput::setVolume(qreal volume) обращается напрямую к драйверу звуковой карты, регулируя громкость виртуального микшера. Мне необходимо делать это внутри программы, не затрагивая системную громкость.
Вообще говоря, функции управления громкостью звука без использования системного микшера не являются частью этих библиотек. Сделать это на уровне приложения совсем несложно - просто увеличивать/уменьшать значения семплов перед отправкой их на звуковую плату (правда, я не знаю что такое crossfade). Документацию обязательно почитаю, попробую перевести свой проект на одну из этих библиотек, хотя бы, в качестве эксперимента. Там всё достаточно просто - смотрите примеры, из них всё понятно. Рекомендую для начала посмотреть на RtAudo там вроде бы попроще концепция, хотя и в portaudio не сильно сложнее.
Название: Re: проблема с QAudioOutput
Отправлено: elijah_olejnik от Октябрь 07, 2014, 05:36
Проблема решилась. Суть в том, что для корректного использования функций этого класса, класс, использующий экземпляр QAudioOutput необходимо запускать в потоке с помощью класса-контроллера, с которым фактически и придётся работать. Всё соединяется через сигналы и слоты. Тогда работа QAudioOutput не будет конфликтовать с другими процессами, в том числе с другим потоком воспроизведения.
|