void QGstreamerAudioProbeControl::bufferProbed() { QAudioBuffer audioBuffer; { QMutexLocker locker(&m_bufferMutex); if (!m_pendingBuffer.isValid()) return; audioBuffer = m_pendingBuffer; } emit audioBufferProbed(audioBuffer); }
/*! Destroys this probe and disconnects from any media object. */ QAudioProbe::~QAudioProbe() { if (d->source) { // Disconnect if (d->probee) { disconnect(d->probee.data(), SIGNAL(audioBufferProbed(QAudioBuffer)), this, SIGNAL(audioBufferProbed(QAudioBuffer))); disconnect(d->probee.data(), SIGNAL(flush()), this, SIGNAL(flush())); } d->source.data()->service()->releaseControl(d->probee.data()); } }
/*! Sets the media object to monitor to \a source. If \a source is zero, this probe will be deactivated and this function wil return true. If the media object does not support monitoring audio, this function will return false. The previous object will no longer be monitored. Passing in the same object will be ignored, but monitoring will continue. */ bool QAudioProbe::setSource(QMediaObject *source) { // Need to: // 1) disconnect from current source if necessary // 2) see if new one has the probe control // 3) connect if so // in case source was destroyed but probe control is still valid if (!d->source && d->probee) { disconnect(d->probee.data(), SIGNAL(audioBufferProbed(QAudioBuffer)), this, SIGNAL(audioBufferProbed(QAudioBuffer))); disconnect(d->probee.data(), SIGNAL(flush()), this, SIGNAL(flush())); d->probee.clear(); } if (source != d->source.data()) { if (d->source) { Q_ASSERT(d->probee); disconnect(d->probee.data(), SIGNAL(audioBufferProbed(QAudioBuffer)), this, SIGNAL(audioBufferProbed(QAudioBuffer))); disconnect(d->probee.data(), SIGNAL(flush()), this, SIGNAL(flush())); d->source.data()->service()->releaseControl(d->probee.data()); d->source.clear(); d->probee.clear(); } if (source) { QMediaService *service = source->service(); if (service) { d->probee = service->requestControl<QMediaAudioProbeControl*>(); } if (d->probee) { connect(d->probee.data(), SIGNAL(audioBufferProbed(QAudioBuffer)), this, SIGNAL(audioBufferProbed(QAudioBuffer))); connect(d->probee.data(), SIGNAL(flush()), this, SIGNAL(flush())); d->source = source; } } } return (!source || d->probee != 0); }
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { Fdata=new fft; Wdata=new wavedata; probe=new QAudioProbe; Ddata=new detaildata; l=new QStringList; label=new QLabel; label->resize( QSize( 500, 100 )); QPalette pa; pa.setColor(QPalette::Background, QColor(0x00,0xff,0x00,0x00)); pa.setColor(QPalette::WindowText,Qt::white); label->setPalette (pa); QFont ft; ft.setPointSize(14); label->setFont(ft); volume=80; order=0; ismute=0; ui->setupUi(this); pushButtonc=0; ui->tableWidget->clearContents(); ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); playList=new QMediaPlaylist; playList->setPlaybackMode(QMediaPlaylist::Loop); player=new QMediaPlayer; player->setPlaylist(playList); player->setVolume(volume); ui->horizontalSlider->setRange(0, 0); ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->tableWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_contextmenu(const QPoint&))); connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged1(qint64))); connect(player, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged1(qint64))); probe->setSource(player); connect(probe,SIGNAL(audioBufferProbed(QAudioBuffer)),Wdata,SLOT(processBuffer(QAudioBuffer))); //connect(probe,SIGNAL(audioBufferProbed(QAudioBuffer)),this,SLOT(test(QAudioBuffer))); connect(Wdata,SIGNAL(wavedataUpdated(wavedata&)),Fdata,SLOT(calculateFFT(wavedata&))); connect(Wdata,SIGNAL(wavedataUpdated(wavedata&)),Ddata,SLOT(processWaveData(wavedata&))); connect(Fdata,SIGNAL(FFTstandby(fft&)),Ddata,SLOT(processFFTData(fft&))); connect(Ddata,SIGNAL(detailDataStandbyT(QString&)),this,SLOT(update_ZhuangBi(QString&))); }
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); createTrayIcon(); createAudioRecorder(); createDeviceList(); createRecordButtonsGroup(); connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(onStateChanged(QMediaRecorder::State))); connect(audioRecorder, SIGNAL(durationChanged(qint64)), this, SLOT(updateProgress(qint64))); connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); connect(recordButtons, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(toggleRecord(QAbstractButton*))); connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer))); }
AudioRecorder::AudioRecorder(QWidget *parent) : QMainWindow(parent), ui(new Ui::AudioRecorder), outputLocationSet(false) { ui->setupUi(this); audioRecorder = new QAudioRecorder(this); probe = new QAudioProbe; connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer))); probe->setSource(audioRecorder); //audio devices ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString())); foreach (const QString &device, audioRecorder->audioInputs()) { ui->audioDeviceBox->addItem(device, QVariant(device)); } //audio codecs ui->audioCodecBox->addItem(tr("Default"), QVariant(QString())); foreach (const QString &codecName, audioRecorder->supportedAudioCodecs()) { ui->audioCodecBox->addItem(codecName, QVariant(codecName)); } //containers ui->containerBox->addItem(tr("Default"), QVariant(QString())); foreach (const QString &containerName, audioRecorder->supportedContainers()) { ui->containerBox->addItem(containerName, QVariant(containerName)); } //sample rate ui->sampleRateBox->addItem(tr("Default"), QVariant(0)); foreach (int sampleRate, audioRecorder->supportedAudioSampleRates()) { ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant( sampleRate)); } //channels ui->channelsBox->addItem(tr("Default"), QVariant(-1)); ui->channelsBox->addItem(QStringLiteral("1"), QVariant(1)); ui->channelsBox->addItem(QStringLiteral("2"), QVariant(2)); ui->channelsBox->addItem(QStringLiteral("4"), QVariant(4)); //quality ui->qualitySlider->setRange(0, int(QMultimedia::VeryHighQuality)); ui->qualitySlider->setValue(int(QMultimedia::NormalQuality)); //bitrates: ui->bitrateBox->addItem(tr("Default"), QVariant(0)); ui->bitrateBox->addItem(QStringLiteral("32000"), QVariant(32000)); ui->bitrateBox->addItem(QStringLiteral("64000"), QVariant(64000)); ui->bitrateBox->addItem(QStringLiteral("96000"), QVariant(96000)); ui->bitrateBox->addItem(QStringLiteral("128000"), QVariant(128000)); connect(audioRecorder, SIGNAL(durationChanged(qint64)), this, SLOT(updateProgress(qint64))); connect(audioRecorder, SIGNAL(statusChanged(QMediaRecorder::Status)), this, SLOT(updateStatus(QMediaRecorder::Status))); connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(onStateChanged(QMediaRecorder::State))); connect(audioRecorder, SIGNAL(error(QMediaRecorder::Error)), this, SLOT(displayErrorMessage())); }
// constructor: warm up all stuff MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) //,audioInfo(QAudioDeviceInfo::defaultInputDevice()) { // draws the ui ui->setupUi(this); // test for saving settings QCoreApplication::setOrganizationName("Agostinho"); /** some settings attempt */ QSettings settings; /*!<aloha */ settings.setValue("alo","maria"); // defines sample size equals to spectrum size sample.resize(SPECSIZE); // threads are as separate processes running within the same // program. for fft calculation, it is better to move it // to another thread to make the calcs faster. // moreover, it will not slow down the ui // fftThread = new QThread(this); calculator = new FFTCalc(); // calculator->moveToThread(fftThread); // launches the new media player player = new QMediaPlayer(); // starts a new playlist playlist = new QMediaPlaylist(); // starts the playlist model playlistModel = new PlaylistModel(this); // tell playlistmodel where is the playlist playlistModel->setPlaylist(playlist); // attach the listView to the playlistModel ui->listViewPlaylist->setModel(playlistModel); // set current index to the first element ui->listViewPlaylist->setCurrentIndex(playlistModel->index(playlist->currentIndex(), 0)); loadPlaylist(); // attachs the playlist to the player player->setPlaylist(playlist); // playlist plays in loop mode. It restarts after last song has finished playing. playlist->setPlaybackMode(QMediaPlaylist::Loop); // this allow the user to select the media it wants to play connect(ui->listViewPlaylist, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(goToItem(QModelIndex))); // if some metadata changed for media, display it somewhere // it seems not work on windows // but works for linux :) connect(player,SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged())); // the media status changed (new stream has arrived) connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus))); // the user selected a new position on music to play // perharps using some scrollbar connect(this,SIGNAL(positionChanged(qint64)), player,SLOT(setPosition(qint64))); connect(player,SIGNAL(volumeChanged(int)), ui->control,SLOT(onVolumeChanged(int))); connect(player,SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(mediaStateChanged(QMediaPlayer::State))); // that is the audio probe object that "listen to" // the music. It will help with fft stuff probe = new QAudioProbe(); // fft is delivered using a QVector<double> but // signal/slot scheme does not recognizes this type by default // therefore, we have to register it qRegisterMetaType< QVector<double> >("QVector<double>"); // here goes the control unit event handlers connect(ui->control, SIGNAL(playPause()), this, SLOT(playPause())); connect(ui->control, SIGNAL(prev()), this, SLOT(prev())); connect(ui->control, SIGNAL(next()), this, SLOT(next())); connect(this, SIGNAL(playPauseChanged(bool)), ui->control,SLOT(onPlayerStateChanged(bool))); // when the music position changes on player, it has to be // informed to the control unit to redraw it ui connect(player, SIGNAL(positionChanged(qint64)), ui->control,SLOT(onElapsedChanged(qint64))); // fft goes here... // if a new audio buffer is ok, we have to make some // calcs (fft) to display the spectrum connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer))); // when fft is available, we deliver it to // the visualization widget connect(this, SIGNAL(spectrumChanged(QVector<double>&)), ui->visualizer,SLOT(loadSamples(QVector<double>&))); // communicate the left and right audio levels... // ...mean levels connect(this, SIGNAL(levels(double,double)), ui->visualizer,SLOT(loadLevels(double,double))); // when fft is available, we deliver it to // the visualization widget //connect(this, SIGNAL(spectrumChanged(QVector<double>&)), // ui->glVisualizer,SLOT(loadSamples(QVector<double>&))); // communicate the left and right audio levels... // ...mean levels //connect(this, SIGNAL(levels(double,double)), // ui->glVisualizer,SLOT(loadLevels(double,double))); // if the user selected a new position on stream to play // we have to tell it to the player connect(ui->control, SIGNAL(elapsedSelected(qint64)), player, SLOT(setPosition(qint64))); // changing audio volume connect(ui->control, SIGNAL(volumeSelected(int)), player, SLOT(setVolume(int))); // calculator is the thead that calcs the ffts we need to display // every time a new spectrum is available, the calculator // emits a calculatedSpectrum signal connect(calculator, SIGNAL(calculatedSpectrum(QVector<double>)), this, SLOT(spectrumAvailable(QVector<double>))); connect(ui->library,SIGNAL(addMediaToPlayList(QString)), SLOT(onAddMediaToPlayList(QString))); // tells the probe what to probe probe->setSource(player); // load directories to library connect(ui->actionLoadDirectory,SIGNAL(triggered()),this,SLOT(onAddFolderToLibrary())); // load a single file to library connect(ui->actionLoadFile,SIGNAL(triggered()),this,SLOT(loadMedia())); // it connects the signals emiteds via the visualizer to the buttons (ui->control) and the lightCycle(ui->widgetInfo) connect(ui->visualizer,SIGNAL(trocaCor(QColor)),ui->control,SLOT(onColorChanged(QColor))); connect(ui->visualizer,SIGNAL(trocaCor(QColor)),ui->widgetInfo,SLOT(changedColor(QColor))); //this->setStyleSheet(QString("QMainWindow {background-color: black}")); }