File indexing completed on 2025-02-09 07:08:06
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im> 0003 * SPDX-FileCopyrightText: 2020-2021 Devin Lin <espidev@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-3.0-or-later 0006 */ 0007 0008 #include <QAudioFormat> 0009 #include <QAudioInput> 0010 #include <QMediaCaptureSession> 0011 0012 #include "audioprober.h" 0013 0014 AudioProber::AudioProber(QObject *parent) 0015 : QAudioDecoder{ parent } 0016 {} 0017 0018 AudioProber::AudioProber(QObject *parent, QMediaRecorder *source) 0019 : QAudioDecoder{ parent } 0020 , m_recorderSource{ source } 0021 { 0022 QAudioFormat format; 0023 // Set up the desired format, for example: 0024 format.setSampleRate(8000); 0025 format.setChannelCount(1); 0026 format.setSampleFormat(QAudioFormat::UInt8); 0027 0028 QAudioDevice device = source->captureSession()->audioInput()->device(); 0029 if (!device.isFormatSupported(format)) { 0030 qWarning() << "Default format not supported, trying to use the nearest."; 0031 } 0032 0033 m_audioSource = new QAudioSource(device, format, this); 0034 0035 // connect to recorder 0036 connect(m_recorderSource, &QMediaRecorder::recorderStateChanged, this, &AudioProber::handleRecorderState); 0037 0038 // loop to add volume bars 0039 volumeBarTimer = new QTimer(this); 0040 connect(volumeBarTimer, &QTimer::timeout, this, &AudioProber::processVolumeBar); 0041 volumeBarTimer->setInterval(150); 0042 } 0043 0044 AudioProber::AudioProber(QObject *parent, QMediaPlayer *source) 0045 : QAudioDecoder{ parent } 0046 , m_playerSource{ source } 0047 { 0048 connect(this, &AudioProber::bufferReady, this, &AudioProber::process); 0049 0050 // connect to player 0051 connect(m_playerSource, &QMediaPlayer::playbackStateChanged, this, &AudioProber::handlePlayerState); 0052 0053 // loop to add volume bars 0054 volumeBarTimer = new QTimer(this); 0055 connect(volumeBarTimer, &QTimer::timeout, this, &AudioProber::processVolumeBar); 0056 volumeBarTimer->setInterval(150); 0057 } 0058 0059 void AudioProber::handleRecorderState(QMediaRecorder::RecorderState state) { 0060 if (state == QMediaRecorder::RecordingState) { 0061 start(); 0062 volumeBarTimer->start(); 0063 } else if (state == QMediaRecorder::PausedState) { 0064 stop(); 0065 volumeBarTimer->stop(); 0066 } else if (state == QMediaRecorder::StoppedState) { 0067 stop(); 0068 volumeBarTimer->stop(); 0069 // clear volumes list 0070 clearVolumesList(); 0071 } 0072 } 0073 0074 void AudioProber::handlePlayerState(QMediaPlayer::PlaybackState state) { 0075 if (state == QMediaPlayer::PlayingState) { 0076 volumeBarTimer->start(); 0077 } else if (state == QMediaPlayer::PausedState) { 0078 volumeBarTimer->stop(); 0079 } else if (state == QMediaPlayer::StoppedState) { 0080 volumeBarTimer->stop(); 0081 // clear volumes list 0082 clearVolumesList(); 0083 } 0084 } 0085 0086 void AudioProber::start() 0087 { 0088 qDebug() << "pang"; 0089 QIODevice *iodevice = m_audioSource->start(); 0090 qDebug() << iodevice; 0091 setSourceDevice(iodevice); 0092 qDebug() << sourceDevice(); 0093 QAudioDecoder::start(); 0094 connect(this, &QAudioDecoder::bufferReady, this, &AudioProber::process); 0095 } 0096 0097 void AudioProber::processVolumeBar() 0098 { 0099 if (isDecoding()) { 0100 // m_audioLen might be 0 0101 const int val = m_audioLen == 0 ? 0 : m_audioSum / m_audioLen; 0102 0103 m_volumesList.append(val); 0104 Q_EMIT volumesListAdded(val); 0105 0106 if (m_volumesList.count() > m_maxVolumes) { 0107 m_volumesList.removeFirst(); 0108 } 0109 0110 Q_EMIT volumesListChanged(); 0111 0112 // index of rectangle to animate 0113 if (m_volumesList.count() != 0) { 0114 m_animationIndex = m_volumesList.count(); 0115 Q_EMIT animationIndexChanged(); 0116 } 0117 0118 m_audioSum = 0; 0119 m_audioLen = 0; 0120 } 0121 } 0122 0123 void AudioProber::process() 0124 { 0125 qDebug() << "ping"; 0126 int sum = 0; 0127 auto buffer = read(); 0128 for (int i = 0; i < buffer.sampleCount(); i++) { 0129 const short *bufferData = buffer.data<short>(); 0130 sum += abs(bufferData[i]); 0131 } 0132 0133 sum /= read().sampleCount(); 0134 0135 m_audioSum += sum; 0136 m_audioLen++; 0137 } 0138 0139 QVariantList AudioProber::volumesList() const 0140 { 0141 return m_volumesList; 0142 } 0143 0144 int AudioProber::maxVolumes() 0145 { 0146 return m_maxVolumes; 0147 } 0148 0149 void AudioProber::setMaxVolumes(int m) 0150 { 0151 m_maxVolumes = m; 0152 Q_EMIT maxVolumesChanged(); 0153 } 0154 0155 int AudioProber::animationIndex() 0156 { 0157 return m_animationIndex; 0158 } 0159 0160 void AudioProber::clearVolumesList() 0161 { 0162 while (!m_volumesList.empty()) 0163 m_volumesList.removeFirst(); 0164 Q_EMIT volumesListChanged(); 0165 Q_EMIT volumesListCleared(); 0166 }