File indexing completed on 2024-03-24 04:45:29
0001 #include "audiotranscribe.h" 0002 #include <QJsonObject> 0003 #include <QJsonArray> 0004 #include <QJsonDocument> 0005 #include <QRandomGenerator> 0006 #include <QDebug> 0007 0008 AudioTranscribe::AudioTranscribe(QObject *parent) 0009 : QObject(parent), 0010 m_controller(Controller::instance()) 0011 { 0012 0013 if (m_controller->status() != Controller::Open){ 0014 m_controller->start(); 0015 } 0016 0017 connect(m_controller, &Controller::socketStatusChanged, this, 0018 [this]() { 0019 if (m_controller->status() == Controller::Open){ 0020 connect(m_controller, &Controller::messageReceived, this, 0021 &AudioTranscribe::onMainSocketMessageReceived); 0022 } 0023 }); 0024 0025 QAudioFormat format; 0026 format.setCodec(QStringLiteral("audio/PCM")); 0027 format.setSampleRate(16000); 0028 format.setSampleSize(16); 0029 format.setChannelCount(1); 0030 format.setByteOrder(QAudioFormat::LittleEndian); 0031 format.setSampleType(QAudioFormat::SignedInt); 0032 0033 QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); 0034 if (!info.isFormatSupported(format)) { 0035 format = info.nearestFormat(format); 0036 format.setSampleRate(16000); 0037 qDebug() << "Raw audio format not supported by backend. Trying the nearest format."; 0038 } 0039 0040 m_audioInput = new QAudioInput(format, this); 0041 } 0042 0043 void AudioTranscribe::start() 0044 { 0045 emit startRequested(); 0046 startRecording(); 0047 m_stage = 1; 0048 } 0049 0050 void AudioTranscribe::stop(){ 0051 emit endRequested(); 0052 endRecording(); 0053 } 0054 0055 void AudioTranscribe::sendData() 0056 { 0057 if (m_controller->status() == Controller::Open){ 0058 QJsonObject root; 0059 qDebug() << "Sending Data"; 0060 root[QStringLiteral("responseid")] = getRequestIdentifier(); 0061 root[QStringLiteral("file")] = QStringLiteral("/tmp/%1_in.raw").arg(m_requestIdentifier); 0062 m_controller->sendRequest(QStringLiteral("libqmycroft.request.transcribe"), root.toVariantMap()); 0063 } 0064 } 0065 0066 void AudioTranscribe::startRecording() 0067 { 0068 destinationFile.setFileName(QStringLiteral("/tmp/%1_in.raw").arg(m_requestIdentifier)); 0069 destinationFile.open( QIODevice::WriteOnly | QIODevice::Truncate ); 0070 m_audioInput->start(&destinationFile); 0071 emit recordingStarted(); 0072 } 0073 0074 void AudioTranscribe::endRecording() 0075 { 0076 m_audioInput->stop(); 0077 destinationFile.close(); 0078 emit recordingEnded(); 0079 sendData(); 0080 m_stage = 0; 0081 } 0082 0083 void AudioTranscribe::generateRequestIdentifier() 0084 { 0085 m_requestIdentifier = QRandomGenerator::global()->bounded(10000, 99999); 0086 emit requestIdentifierGenerated(); 0087 } 0088 0089 QString AudioTranscribe::getRequestIdentifier() 0090 { 0091 return QString::number(m_requestIdentifier); 0092 } 0093 0094 void AudioTranscribe::onMainSocketMessageReceived(const QString &message) 0095 { 0096 auto doc = QJsonDocument::fromJson(message.toUtf8()); 0097 0098 if (doc.isEmpty()) { 0099 qWarning() << "Empty or invalid JSON message arrived on the main socket:" << message; 0100 return; 0101 } 0102 0103 auto type = doc[QStringLiteral("type")].toString(); 0104 if(type == QStringLiteral("libqmycroft.request.transcribe.result")){ 0105 QString targetResponseId = doc[QStringLiteral("data")][QStringLiteral("targetResponseId")].toString(); 0106 QString targetResult = doc[QStringLiteral("data")][QStringLiteral("targetResult")].toString(); 0107 if(targetResponseId == getRequestIdentifier()) { 0108 emit responseReceived(targetResult); 0109 } 0110 } 0111 } 0112 0113 AudioTranscribe::Status AudioTranscribe::status() const 0114 { 0115 switch(m_stage) 0116 { 0117 case 0: 0118 return Inactive; 0119 case 1: 0120 return Active; 0121 default: 0122 return Inactive; 0123 } 0124 }