Bladeren bron

V1.5
1、修改了录音文件的录制方式,可以整点对其了
2、提交了测试

Apple 1 week geleden
bovenliggende
commit
e48ca6099e

+ 2 - 2
Server/ThreadCalculate/NoiseDetectThread.cpp

@@ -462,7 +462,7 @@ void NoiseDetectThread::saveResultOnlyOneItem()
                 m_currentAlarmInfo.RoadInfo = m_threadInfo.compareItemInfo.mapRoad.first();
                 m_currentAlarmInfo.AlarmType = EAlarmType::EAT_Noise;
                 /* 向前推算噪音开始时间,开始时间需要向前推 n次噪音检测的时间 x 单次噪音检测需要的时间,单位秒 */
-                int nNoiseDetectTime = m_noiseDetectParam.nNoiseDetectContinueCount * 1;
+                int nNoiseDetectTime = m_noiseDetectParam.nNoiseDetectContinueCount * m_noiseDetectParam.nNoiseOneDetectDuration;
                 QDateTime startTime = m_leftRightData.startTime;
                 startTime = startTime.addSecs(-nNoiseDetectTime);
                 m_currentAlarmInfo.StartTime = startTime;
@@ -504,7 +504,7 @@ void NoiseDetectThread::saveResultOnlyOneItem()
                 }
                 /* 写入数据库,并清空时间 */
                 WriteDB.addAlarmInfo(m_currentAlarmInfo);
-                m_currentAlarmInfo = AlarmInfo_t(); // 清空当前报警信息         
+                m_currentAlarmInfo = AlarmInfo_t(); // 清空当前报警信息
             }
             
         }

+ 3 - 2
Server/ThreadRecord/AudioRecord/AudioRecord.cpp

@@ -310,11 +310,12 @@ int AudioRecord::recordAudio(char* buffer, int32_t bufferSize, int32_t recordFra
 		SPDLOG_ERROR("缓冲区大小不足,无法存储 {} 帧数据", recordFrames);
 		return -1;
 	}
+	/* 返回值是-32,提示 断开的管道 */
 	auto readFrames = snd_pcm_readi(m_captureHandle, buffer, recordFrames);
 	if (readFrames < 0)
 	{
-		SPDLOG_ERROR("获取录音数据失败: {}", snd_strerror(readFrames));
-		return -1;
+		SPDLOG_ERROR("获取录音数据失败:{} , {}", readFrames, snd_strerror(readFrames));
+		return -2;
 	}
 	
 	return readFrames * m_oneSampleSize; // 返回读取到的字节数

+ 8 - 0
Server/ThreadRecord/AudioRecord/AudioRecord.h

@@ -80,6 +80,14 @@ namespace AudioDevice
 class AudioRecord
 {
 
+public:
+    enum eAudioError
+    {
+        Audio_OK = 0,
+        Audio_ERROR = 1,
+        Audio_DisconnectPipe = 2        /* 断开的管道 */
+    };
+
 public:
     AudioRecord() = default;
     ~AudioRecord() = default;

+ 217 - 90
Server/ThreadRecord/CreateRecordFileThread.cpp

@@ -37,12 +37,13 @@ bool CreateRecordFileThread::setData(const AudioSrcData& srcData)
     }
 
     /* ------------------------------------------------------------------------------- */
-    /* 先写入记录报警文件的环形缓冲区 */
+    /* 写入数据到环形缓冲区 */
     {
         std::lock_guard<std::mutex> lock(m_ringQueue.mutex);
         auto oldData = m_ringQueue.push(new AudioSrcData(srcData));
         /* 新的元素数加1 */
         m_numNewAlarmSeconds++;
+        m_numNewRecordSeconds++;
         if(oldData != nullptr)
         {
             delete oldData;
@@ -50,37 +51,6 @@ bool CreateRecordFileThread::setData(const AudioSrcData& srcData)
         }
     }
     
-    /* ------------------------------------------------------------------------------- */
-    if(m_isRequireRecord.load() == false)
-    {
-        /* 如果不需要录音,则直接返回 */
-        return true;
-    }
-    /* 锁定长文件录音缓冲区 */
-    std::lock_guard<std::mutex> lock(m_mutexBuffer);
-    /* 如果缓冲区没有分配内存,先分配 */
-    if(m_bufferData.pData == nullptr)
-    {
-        if(!m_bufferData.allocateMemory(m_writeCriticalSize * 3))
-        {
-            SPDLOG_LOGGER_ERROR(m_logger, "{} 分配缓冲区内存失败", m_logBase);
-            return false;
-        }
-    }
-    /* 添加数据到缓冲区 */
-    int32_t writtenSize = m_bufferData.appendData(srcData.pData, srcData.dataSize);
-    if(writtenSize == 0)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "{} 添加数据到缓冲区失败", m_logBase);
-        return false;
-    }
-    /* 记录日期 */
-    if(m_bufferData.startTime.isNull() || !m_bufferData.startTime.isValid())
-    {
-        m_bufferData.startTime = srcData.startTime;
-    }
-    m_bufferData.endTime = srcData.endTime;
-
     // SPDLOG_LOGGER_DEBUG(m_logger, "{} 设置数据,dataSize: {}, startTime: {}, endTime: {}",
     //     m_logBase, m_bufferData.dataSize, m_bufferData.startTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), m_bufferData.endTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
 
@@ -229,7 +199,6 @@ void CreateRecordFileThread::task()
         /*--------------------------------------------------------------
         * 写入长记录文件
         *--------------------------------------------------------------*/
-        
         writeLongRecordFile();
         
     }
@@ -253,15 +222,17 @@ bool CreateRecordFileThread::initData()
     /* 一秒的数据大小 */
     m_oneSecondSize = m_sampleRate * m_numChannels * (m_bitsPerSample / 8);
     /* 一次写入的大小,10秒钟 */
-    m_writeCriticalSize = m_oneSecondSize * 10;
+    // m_writeCriticalSize = m_oneSecondSize * 10;
     /* 一小时数据大小 */
-    m_oneHourSize = m_oneSecondSize * 60 * 60;
+    // m_oneHourSize = m_oneSecondSize * 60 * 60;
     /* 给缓存分配空间 */
-    m_bufferData.allocateMemory(m_writeCriticalSize * 3);
-    m_srcData.allocateMemory(m_writeCriticalSize * 3);
+    // m_bufferData.allocateMemory(m_writeCriticalSize * 3);
+    // m_srcData.allocateMemory(m_writeCriticalSize * 3);
 
     /* 设置环形队列大小 */
-    m_ringQueue.setQueueCapacity(GInfo.queueElementCount());
+    // m_ringQueue.setQueueCapacity(GInfo.queueElementCount());
+    m_ringQueue.setQueueCapacity(180);  /* 3分钟数据 */
+
 
     return true;
 }
@@ -270,9 +241,9 @@ bool CreateRecordFileThread::initData()
 void CreateRecordFileThread::clearData()
 {
     /* 清理缓存数据 */
-    std::lock_guard<std::mutex> lock(m_mutexBuffer);
-    m_bufferData.clear();
-    m_srcData.clear();
+    // std::lock_guard<std::mutex> lock(m_mutexBuffer);
+    // m_bufferData.clear();
+    // m_srcData.clear();
 
     std::lock_guard<std::mutex> lockSrcData(m_ringQueue.mutex);
     while(!m_ringQueue.isEmpty())
@@ -296,44 +267,124 @@ bool CreateRecordFileThread::writeLongRecordFile()
     if(m_isRequireRecord.load() == false)
     {
         /* 没有对比项信息,不进行录音 */
+        /* 判断当前有没有录音,如果有,则结束录音 */
+
+        m_numNewRecordSeconds = 0;
         return true;
     }
 
-    /* 判断缓存是否达到写入数据的临界值 */
+    /* 取出最新的 m_numNewRecordSeconds 个音频数据 */
+    std::list<AudioSrcData*> newList;
     {
-        std::lock_guard<std::mutex> lock(m_mutexBuffer);
-        if(m_bufferData.dataSize < m_writeCriticalSize)
+        std::lock_guard<std::mutex> lock(m_ringQueue.mutex);
+        /* 判断缓存是否达到写入数据的临界值 */
+        if(m_numNewRecordSeconds < 10)
         {
             return true; // 缓存数据不足,继续等待
         }
-        /* 数据足够了将缓冲区数据拷贝出来 */
-        memcpy(m_srcData.pData, m_bufferData.pData, m_bufferData.dataSize);
-        m_srcData.dataSize = m_bufferData.dataSize;
-        m_srcData.startTime = m_bufferData.startTime;
-        m_srcData.endTime = m_bufferData.endTime;
-        /* 清空缓冲区数据 */
-        m_bufferData.clear();
+
+        int startPos = m_ringQueue.QueueSize() - m_numNewRecordSeconds;
+        if(startPos < 0)
+        {
+            startPos = 0;
+        }
+        for(int i = startPos; i < m_ringQueue.QueueSize(); i++)
+        {
+            newList.push_back(m_ringQueue[i]);
+        }
     }
-    // SPDLOG_LOGGER_DEBUG(m_logger, "{} 设置数据,dataSize: {}, startTime: {}, endTime: {}",
-    // m_logBase, m_srcData.dataSize, m_srcData.startTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), m_srcData.endTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
+
+
     /*--------------------------------------------------------------
      * 打开文件。写入的时候判断是否到达了整点,如果到达了整点,则关闭文件
      * 重新创建一个新的文件
      *--------------------------------------------------------------*/
-    bool isNewFile = false;
+    bool isPassed = isOneHourPassed(newList);
+
+    /* 判断 newList 中有没有跨过整点,如果有则分开,分别写入 */
+    std::list<AudioSrcData*> writeList;
+    std::list<AudioSrcData*> writeNewFileList;
+
+    if(isPassed)
+    {
+        /* 跨过了整点 */
+        for(const auto& it : newList)
+        {
+            if(it == nullptr || it->dataSize == 0)
+            {
+                continue;
+            }
+            if(it->startTime.time().minute() == 59)
+            {
+                writeList.push_back(it);
+            }else {
+                writeNewFileList.push_back(it);
+            }
+        }
+    } else {
+        writeList = newList;
+    }
+    
+    /* 判断是不是刚启动的新文件 */
     if(m_writtenSize == 0)
+    {
+        if(isPassed)
+        {
+            /* 刚启动,并且这几秒内也跨过了整点,直接写入并结束这个文件 */
+            writeRecordFileData(writeList, true, true);
+            /* 写新的文件 */
+            writeRecordFileData(writeNewFileList, true, false);
+        }else {
+            /* 刚启动,并且没有跨过整点,直接写入 */
+            writeRecordFileData(writeList, true, false);
+        }
+    }else 
+    {
+        if(isPassed)
+        {
+            if(writeList.size() == 0)
+            {
+                /* 跨过了整点,但是没有数据需要写入 */
+                endRecordFile();
+            }else {
+                /* 不是新文件,并且跨过了整点,先写完这个文件,然后结束 */
+                writeRecordFileData(writeList, false, true);
+            }
+            /* 再写新的文件 */
+            writeRecordFileData(writeNewFileList, true, false);
+        }else {
+            /* 不是新文件,也没有跨过整点,直接写入 */
+            writeRecordFileData(writeList, false, false);
+        }
+    }
+    
+
+    m_numNewRecordSeconds = 0;
+    return true;
+}
+
+/* 写入数据 */
+bool CreateRecordFileThread::writeRecordFileData(const std::list<AudioSrcData*>& dataList, bool isNewFile, bool isRecordCompleted)
+{
+    if(dataList.empty())
+    {
+        return true;
+    }
+    if(isNewFile)
     {
         /* 如果没有写入过数据,则是新文件 */
-        isNewFile = true;
-        m_writtenStartTime = m_srcData.startTime;   // 记录开始时间
+        m_writtenStartTime = dataList.front()->startTime;
         m_writtenNowTime = m_writtenStartTime;
         // SPDLOG_LOGGER_WARN(m_logger, "新录音文件: {} - {}", m_writtenStartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
         //     m_writtenNowTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
     }
     /* 设置今日目录 */
-    if(!setTodayPath(isNewFile))
+    if(isNewFile)
     {
-        return false;
+        if(!setTodayPath(isNewFile))
+        {
+            return false;
+        }
     }
     
     /* 打开文件 */
@@ -347,7 +398,7 @@ bool CreateRecordFileThread::writeLongRecordFile()
             m_writtenStartTime = QDateTime::currentDateTime(); // 重新开始时间
             m_writtenNowTime = m_writtenStartTime; // 重新开始时间
             m_wavFileName.clear(); // 清空文件名
-            m_srcData.clear(); // 清空缓冲区数据
+            // m_srcData.clear(); // 清空缓冲区数据
             m_openFileErrorSize = 0; // 重置错误次数
             return false; // 重新开始记录
         }
@@ -356,23 +407,34 @@ bool CreateRecordFileThread::writeLongRecordFile()
      * 将数据写入文件,并记录其携带的时间和写入的数据大小
      *--------------------------------------------------------------*/
     int64_t wSize = 0;
+    bool isWriteSucess = true;
     {
-        std::lock_guard<std::mutex> lock(m_mutexBuffer);
-        wSize = wavFile.write(m_srcData.pData, m_srcData.dataSize);
-        /* 记录当前结束时间 */
-        m_writtenNowTime = m_srcData.endTime;
-        /* 清空缓冲区 */
-        m_srcData.clear();
+        for(auto it : dataList)
+        {
+            if(it == nullptr || it->dataSize == 0)
+            {
+                continue;
+            }
+            int64_t thisWSize = wavFile.write(it->pData, it->dataSize);
+            if(thisWSize > 0)
+            {
+                wSize += thisWSize;
+                m_writtenNowTime = it->endTime; // 记录当前结束时间
+            }else {
+                isWriteSucess = false;
+                break;
+            }
+        }
     }
-    if(wSize < 0)
+    if(isWriteSucess == false)
     {
         SPDLOG_LOGGER_ERROR(m_logger, "{} 写入WAV文件失败: {}", m_logBase, wavFile.errorString().toStdString());
         SPDLOG_LOGGER_WARN(m_logger, "文件路径:{}", m_wavFileName.toStdString());
         wavFile.close();
         return false;
-    } else {
-        SPDLOG_LOGGER_TRACE(m_logger, "{} 写入WAV文件成功: {}, 大小: {} 字节", m_logBase, m_wavFileName.toStdString(), wSize);
     }
+    SPDLOG_LOGGER_TRACE(m_logger, "{} 写入WAV文件成功: {}, 大小: {} 字节", m_logBase, m_wavFileName.toStdString(), wSize);
+    
     wavFile.close();
     // SPDLOG_LOGGER_DEBUG(m_logger, "写入录音文件成功, 写入的时间段: {} - {}", 
     //     m_writtenStartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), m_writtenNowTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
@@ -393,9 +455,8 @@ bool CreateRecordFileThread::writeLongRecordFile()
         SPDLOG_LOGGER_ERROR(m_logger, "{} 修改文件名失败: {} -> {}", m_logBase, m_wavFileName.toStdString(), newFileName.toStdString());
     }
     
-    /* 判断是否过了整点 */
-    bool isRecordCompleted = false;
-    if(isOneHourPassed())
+    /* 判断是否需要结束文件 */
+    if(isRecordCompleted)
     {
         /* 修改文件头中记录的数据大小 */
         m_wavHeader.setDataSize(m_writtenSize);
@@ -403,7 +464,6 @@ bool CreateRecordFileThread::writeLongRecordFile()
         modifyWavFileHeader(m_wavFileName, m_wavHeader);
         SPDLOG_LOGGER_INFO(m_logger, "{} 结束记录一个文件: {}, 已写入大小: {} 字节", 
             m_logBase, m_wavFileName.toStdString(), m_writtenSize);
-        isRecordCompleted = true;
     }
 
     /* 更新文件信息到数据库 */
@@ -420,7 +480,31 @@ bool CreateRecordFileThread::writeLongRecordFile()
         m_openFileErrorSize = 0;                // 重置错误次数
     }
 
+    return true;
+}
 
+/* 结束文件录制 */
+bool CreateRecordFileThread::endRecordFile()
+{
+
+    /* 修改文件头中记录的数据大小 */
+    m_wavHeader.setDataSize(m_writtenSize);
+    m_wavHeader.calculateDerivedFields();
+    modifyWavFileHeader(m_wavFileName, m_wavHeader);
+    SPDLOG_LOGGER_INFO(m_logger, "{} 结束记录一个文件: {}, 已写入大小: {} 字节", 
+        m_logBase, m_wavFileName.toStdString(), m_writtenSize);
+
+
+    /* 更新文件信息到数据库 */
+    updateRecordFileInfoToDB(false, true);
+
+    /* 清空已经结束的文件信息 */
+    m_writtenSize = 0;
+    m_writtenStartTime = QDateTime();       // 重新开始时间
+    m_writtenNowTime = QDateTime();         // 重新开始时间
+    m_wavFileName.clear();                  // 清空文件名
+    m_openFileErrorSize = 0;                // 重置错误次数
+    
     return true;
 }
 
@@ -538,25 +622,59 @@ QString CreateRecordFileThread::generateFileName(const QDateTime& startTime, con
 
 
 /* 判断是否过了整点 */
-bool CreateRecordFileThread::isOneHourPassed()
+// bool CreateRecordFileThread::isOneHourPassed()
+// {
+//     if(m_writtenSize >= m_oneHourSize)
+//     {
+//         // 已经写入的数据大小超过了一小时的大小
+//         return true;
+//     }
+//     /* 下面是判断刚启动的时候,到下一个整点不足1小时,也会保存文件 */
+//     int minute = m_writtenNowTime.time().minute();
+//     bool isPassed = false;
+//     /* 如果当前时间的分钟数小于等于2,并且已经写入的大小超过三分钟大小 */
+//     if( (minute <= 2) && (m_writtenSize > m_oneSecondSize * 60 * 3) )
+//     {
+//         isPassed = true;
+//     }
+
+//     return isPassed;
+// }
+
+bool CreateRecordFileThread::isOneHourPassed(const std::list<AudioSrcData*>& dataList)
 {
-    if(m_writtenSize >= m_oneHourSize)
+    if(dataList.empty())
     {
-        // 已经写入的数据大小超过了一小时的大小
-        return true;
+        return false;
     }
-    /* 下面是判断刚启动的时候,到下一个整点不足1小时,也会保存文件 */
-    int minute = m_writtenNowTime.time().minute();
-    bool isPassed = false;
-    /* 如果当前时间的分钟数小于等于2,并且已经写入的大小超过三分钟大小 */
-    if( (minute <= 2) && (m_writtenSize > m_oneSecondSize * 60 * 3) )
+    bool has59Minute = false;
+    bool has00Minute = false;
+    /* 计算这些数据中是否跨过了整点 */
+    for(const auto& it : dataList)
     {
-        isPassed = true;
+        if(it == nullptr || it->dataSize == 0)
+        {
+            continue;
+        }
+        if(it->startTime.time().minute() == 59)
+        {
+            has59Minute = true;
+        }
+        if(it->startTime.time().minute() == 0)
+        {
+            has00Minute = true;
+        }
+    }
+    if(has59Minute && has00Minute)
+    {
+        return true;
     }
 
-    return isPassed;
+    return false;
 }
 
+
+
 /* 更新文件信息到数据库 */
 void CreateRecordFileThread::updateRecordFileInfoToDB(bool isNewFile, bool isRecordCompleted)
 {
@@ -616,7 +734,7 @@ QString CreateRecordFileThread::generateAlarmFileName(const AlarmValue_t& value,
         
         /* 拼接文件夹路径 */
         retFileName = itemDir.filePath(fileName);
-        SPDLOG_LOGGER_DEBUG(m_logger, "{} 生成新的报警文件名: {}", m_logBase, retFileName.toStdString());
+        // SPDLOG_LOGGER_DEBUG(m_logger, "{} 生成新的报警文件名: {}", m_logBase, retFileName.toStdString());
     }else 
     {
         /* 已有的文件,是报警结束的文件名 */
@@ -627,7 +745,7 @@ QString CreateRecordFileThread::generateAlarmFileName(const AlarmValue_t& value,
         /* 替换掉原来的结束时间 */
         retFileName.replace("-.wav", QString("-%1.wav").arg(endTimeStr));
 
-        SPDLOG_LOGGER_DEBUG(m_logger, "{} 原文件名:{} 生成报警结束文件名: {}", m_logBase, value.fileName.toStdString(), retFileName.toStdString());
+        // SPDLOG_LOGGER_DEBUG(m_logger, "{} 原文件名:{} 生成报警结束文件名: {}", m_logBase, value.fileName.toStdString(), retFileName.toStdString());
     }
 
     return retFileName;
@@ -637,9 +755,9 @@ QString CreateRecordFileThread::generateAlarmFileName(const AlarmValue_t& value,
 /* 写入报警文件 */
 void CreateRecordFileThread::writeAlarmFile()
 {
-    /* 新文件,从报警时间往前推10秒写入 */
+    /* 取出环形队列中后100秒的数据,前面20秒给环形队列满的时候缓冲使用 */
     std::list<AudioSrcData*> newDataList;
-    int writeSize = m_numNewAlarmSeconds > 10 ? m_numNewAlarmSeconds : 10;
+    int writeSize = m_numNewAlarmSeconds > 120 ? m_numNewAlarmSeconds : 120;
     {
         std::lock_guard<std::mutex> lock(m_ringQueue.mutex);
         /* 取出环形队列中的数据 */
@@ -703,18 +821,20 @@ void CreateRecordFileThread::createNewAlarmFile(AlarmValue_t& value, const std::
     value.fileName = generateAlarmFileName(value, true);
     SPDLOG_LOGGER_INFO(m_logger, "{} 开始写入报警文件: {}", m_logBase, value.fileName.toStdString());
     
-    /* 计算出报警开始位置在报警文件中的偏移,这个偏移值在设置结束的时候取出 */
+    /* 计算出报警开始时间在报警文件中的位置 */
+    int startPos = 0;
     for(const auto& audioData : dataList)
     {
         if(audioData == nullptr || audioData->pData == nullptr || audioData->dataSize == 0)
         {
             continue; // 跳过空数据
         }
-        if(audioData->startTime <= value.startTime)
+        if(audioData->startTime >= value.startTime)
         {
             /* 计算报警开始位置 */
-            value.alarmStartPos = audioData->startTime.secsTo(value.startTime);
+            break;
         }
+        startPos++;
     }
     
     /* 打开文件 */
@@ -735,12 +855,18 @@ void CreateRecordFileThread::createNewAlarmFile(AlarmValue_t& value, const std::
     wavFile.write(reinterpret_cast<const char*>(&value.wavHeader), sizeof(WavHeader));
 
     /* 写入音频数据到文件 */
+    int nowPos = 0;
     for(auto& audioData : dataList)
     {
         if(audioData == nullptr || audioData->pData == nullptr || audioData->dataSize == 0)
         {
             continue; // 跳过空数据
         }
+        if(nowPos < startPos)
+        {
+            nowPos++;
+            continue; // 跳过前面的数据
+        }
         auto writeSize = wavFile.write(reinterpret_cast<const char*>(audioData->pData), audioData->dataSize);
         if(writeSize < 0)
         {
@@ -775,6 +901,7 @@ void CreateRecordFileThread::writeNewAlarmFileData(std::list<AudioSrcData*> data
         return; // 没有新的报警信息
     }
     
+    
     /* 创建新文件并写入数据 */
     for(auto& alarmInfo : m_mapAlarmFile)
     {

+ 13 - 10
Server/ThreadRecord/CreateRecordFileThread.h

@@ -132,6 +132,10 @@ private:
     /*===============================================================================*/
     /* 写入长记录文件 */
     bool writeLongRecordFile();
+    /* 写入数据 */
+    bool writeRecordFileData(const std::list<AudioSrcData*>& dataList, bool isNewFile, bool isRecordCompleted = false);
+    /* 结束文件录制 */
+    bool endRecordFile();
     /* 设置今日目录 */
     inline bool setTodayPath(bool isNewFile);
     /* 打开文件 */
@@ -141,7 +145,8 @@ private:
     /* 生成文件名 */
     inline QString generateFileName(const QDateTime& startTime, const QDateTime& endTime) const;
     /* 判断是否过了整点 */
-    inline bool isOneHourPassed();
+    // inline bool isOneHourPassed();
+    inline bool isOneHourPassed(const std::list<AudioSrcData*>& dataList);
     /* 更新文件信息到数据库 */
     void updateRecordFileInfoToDB(bool isNewFile, bool isRecordCompleted);
 
@@ -167,19 +172,17 @@ private:
         使用条件变量,一有报警即会创建文件写入 */
     std::condition_variable m_cond_var;     /* 条件变量,用于线程间同步 */
     std::mutex m_mutexCondVar;              /* 条件变量的互斥锁 */
+
+    RingQueueManualMutex<AudioSrcData*> m_ringQueue; /* 环形队列,存储报警文件数据 */
+    QDateTime m_alarmWrittenTime;           /* 报警文件中环形队列已写入文件的时间 */
     /* ------------------------- 录音文件 ------------------------- */
     /* 对比项通道信息列表,记录当前对比项的通道信息,如果没有对比项信息就停止录音 */
     std::mutex m_mutexCompareItemRoadInfo;
     QList<OneCompareItemRoadInfo_t> m_listCompareItemRoadInfo;
     std::atomic_bool m_isRequireRecord = false;    /* 是否需要录音 */
 
-    /* 临时缓存数据, 一定时间写一次,分配两倍的大小 */
-    std::mutex m_mutexBuffer;
-    AudioSrcData m_bufferData;              /* 音频数据缓冲区 */
-    AudioSrcData m_srcData;                 /* 当前的音频数据,满一定时间后会拷贝到这里,然后写入数据,防止写入的时候阻塞缓冲区 */
-
-    int32_t m_writeCriticalSize = 0;        /* 写入文件的临界大小,单位:字节,缓存超过这个大小就写入文件 */
-    int32_t m_oneHourSize = 0;              /* 一小时的音频数据大小 */
+    // int32_t m_writeCriticalSize = 0;        /* 写入文件的临界大小,单位:字节,缓存超过这个大小就写入文件 */
+    // int32_t m_oneHourSize = 0;              /* 一小时的音频数据大小 */
 
     QDir m_todayDir;                        /* 今日目录 */
     QDate m_todayDateRecord;                /* 今日日期,记录长文件用 */
@@ -190,6 +193,8 @@ private:
     QDateTime m_writtenStartTime;           /* 已经写入数据的开始时间点 */
     QDateTime m_writtenNowTime;             /* 已经写入数据的最后时间点 */
 
+    int m_numNewRecordSeconds = 0;          /* 新的录音文件的秒数,新加入的录音文件的秒数,每次写完后清零 */
+
     
 
     /* ------------------------- 报警文件 ------------------------- */
@@ -201,8 +206,6 @@ private:
     QDir m_todayDirAlarm;                   /* 今日报警目录,这个目录只到日期,里面的子文件夹是对比项相关的 */
     QDate m_todayDateAlarm;                 /* 今日日期,记录报警文件用 */
 
-    RingQueueManualMutex<AudioSrcData*> m_ringQueue; /* 环形队列,存储报警文件数据 */
-    QDateTime m_alarmWrittenTime;           /* 报警文件中环形队列已写入文件的时间 */
     int m_numNewAlarmSeconds = 0;           /* 新的报警文件的秒数,新加入的报警文件的秒数,每次写完后清零 */
 };
 

+ 21 - 1
Server/ThreadRecord/RecordThread.cpp

@@ -68,6 +68,9 @@ void RecordThread::task()
     }
 #endif /* RECORD_READFILE */
 
+    /* 重连声卡的次数,超过5次就退出 */
+    int reconnectSize = 0;
+
     /* 获取分派数据线程 */
     while(m_assignThread == nullptr)
     {
@@ -88,11 +91,28 @@ void RecordThread::task()
     #if(RECORD_READFILE)
         testGetData(m_pRecordBuffer, m_recordBufferSize, m_oneRecordCount);
     #else
-        if(!m_audioRecord.recordAudio(m_pRecordBuffer, m_recordBufferSize, m_oneRecordCount))
+        int ret = m_audioRecord.recordAudio(m_pRecordBuffer, m_recordBufferSize, m_oneRecordCount);
+        if(ret == -1)
         {
             SPDLOG_LOGGER_ERROR(m_logger, "{} 录音失败,可能是声卡被占用或其他错误", m_logBase);
             break;  /* 录音失败,退出循环 */
+        }else if(ret == -2) 
+        {
+            SPDLOG_LOGGER_INFO(m_logger, "{} 关闭声卡录音通道,尝试重新打开", m_logBase);
+            /* 断开的管道,重新初始化声卡通道 */
+            m_audioRecord.closeRecordChannel();
+            if(!m_audioRecord.openRecordChannel(m_audioRecordDesc))
+            {
+                SPDLOG_LOGGER_ERROR(m_logger, "{} 重新打开声卡通道失败: {}", m_logBase, m_audioRecordDesc);
+                reconnectSize++;
+                if(reconnectSize > 5)
+                {
+                    break;
+                }
+                continue;
+            }
         }
+        reconnectSize = 0;
     #endif /* RECORD_READFILE */
 
         // std::chrono::steady_clock::time_point recordTime = std::chrono::steady_clock::now();

+ 1 - 1
SettingLibrary/Modules/AICompare/aicomparewidget.cpp

@@ -31,7 +31,7 @@ AICompareWidget::AICompareWidget(QWidget *parent) :
 
     /* ai对比持续次数 */
     ui->lineEdit_compareCount->setValidator(new QIntValidator(1, 10, this));
-    ui->lineEdit_compareCount->setPlaceholderText("请输入, 持续对比次数限制1-10次");
+    ui->lineEdit_compareCount->setPlaceholderText("请输入, 限制1-10次");
 
     /* 不相似度阈值 */
     ui->lineEdit_notSimilarThrehold->setValidator(new StrictDoubleValidator(0.0, 1.0, 3, this));

+ 2 - 2
show1/widget.cpp

@@ -32,8 +32,8 @@ Widget::Widget(QWidget *parent) :
     stInitData initData;
     initData.strWebAddr = "http://192.1.3.133:31000/v6/";
 
-    // initData.strDBID = "cf6b57fa3d9841e22c3c897e6b8e66b8";       /* 达梦数据库 */
-    initData.strDBID = "3b8889a0d58b8d71affc04bc27d14e42";          /* GBase */
+    initData.strDBID = "cf6b57fa3d9841e22c3c897e6b8e66b8";       /* 达梦数据库 */
+    // initData.strDBID = "3b8889a0d58b8d71affc04bc27d14e42";          /* GBase */
     // initData.strDBID = "a75e46623562077b76334a2e02616747";       /* MySQL */
 
     DoInit(&initData);