123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- #include "AudioData.h"
- #include "spdlog/spdlog.h"
- #include "GlobalInfo.h"
- #include <QFile>
- #include <cstring>
- /* =========================================================================================
- * WAV文件头信息结构体及其功能函数
- * =========================================================================================*/
- /* 修改wav文件已写入的大小 */
- bool modifyWavFileHeader(const QString& fileName, WavHeader& header)
- {
- QFile wavFile(fileName);
- if(!wavFile.open(QIODevice::ReadWrite))
- {
- SPDLOG_WARN("打开WAV文件失败: {}", fileName.toStdString());
- return false;
- }
- wavFile.seek(0); // 定位到文件开头
- wavFile.write(reinterpret_cast<const char*>(&header), sizeof(WavHeader));
- wavFile.close();
- return true;
- }
- /* 修改录音文件名 */
- bool modifyFileName(const QString& fileName, const QString& newFileName)
- {
- if(fileName.isEmpty() || newFileName.isEmpty())
- {
- SPDLOG_WARN("文件名或新文件名为空,无法修改");
- return false;
- }
- if(!QFile::rename(fileName, newFileName))
- {
- SPDLOG_ERROR("修改文件名失败: {} -> {}", fileName.toStdString(), newFileName.toStdString());
- return false;
- }
- return true;
- }
- /* =================================================================
- * OneSecondData
- * ================================================================= */
- OneSecondData::OneSecondData()
- {
- Init();
- }
- OneSecondData::~OneSecondData()
- {
- }
- OneSecondData::OneSecondData(const OneSecondData& obj)
- {
- *this = obj;
- }
- OneSecondData& OneSecondData::operator=(const OneSecondData &obj)
- {
- nAudioError = obj.nAudioError;
- for(int i = 0; i < VOLUME_INFO_NUM; ++i)
- {
- aryLeftDB[i] = obj.aryLeftDB[i];
- aryRightDB[i] = obj.aryRightDB[i];
- aryPhase[i] = obj.aryPhase[i];
- }
- startTime = obj.startTime;
- endTime = obj.endTime;
- return *this;
- }
- void OneSecondData::Init()
- {
- nAudioError = 0;
- for(int i = 0; i < VOLUME_INFO_NUM; ++i)
- {
- aryLeftDB[i] = VOLUME_MIN_BD;
- aryRightDB[i] = VOLUME_MIN_BD;
- aryPhase[i] = 0.00;
- }
- }
- int OneSecondData::calSilentDB(const StVolumeParam ¶m)
- {
- if(!param.GetSilentSwitch()) return 0;
- int nNum = VOLUME_INFO_NUM;
- for(int i = 0; i < VOLUME_INFO_NUM; ++i)
- {
- if(aryLeftDB[i] > param.GetSilentThreshold() || aryRightDB[i] > param.GetSilentThreshold())
- {
- --nNum;
- }
- }
- return nNum;
- }
- bool OneSecondData::CalcDBOneSecond(const StVolumeParam ¶m)
- {
- if(!param.GetSilentSwitch()) return false;
- bool bSilence = false;
- int nNum = calSilentDB(param);
- nNum = nNum * 100;
- if (nNum >= param.GetSilentSensitivity() * VOLUME_INFO_NUM)
- {
- bSilence = true;
- }
- return bSilence;
- }
- // 判定过载
- int OneSecondData::CalcOverload(const StVolumeParam ¶m)
- {
- if(!param.GetOverloadSwitch()) return 0;
- int nOverloadNum = 0;
- for(int i = 0; i < VOLUME_INFO_NUM; ++i)
- {
- if(aryLeftDB[i] >= param.GetOverloadThreshold() || aryRightDB[i] >= param.GetOverloadThreshold())
- {
- ++nOverloadNum;
- }
- }
- return nOverloadNum;
- }
- /* 判断1s的过载 */
- bool OneSecondData::CalcOverloadOneSecond(const StVolumeParam ¶m)
- {
- // 25 10
- // ---- > ----
- // 50 100
- bool bOverload = false;
- int nOverloadNum = CalcOverload(param);
- nOverloadNum = nOverloadNum * 100;
- int nNum = param.GetOverloadSensitivity() * VOLUME_INFO_NUM;
- if (nOverloadNum >= nNum)
- {
- bOverload = true;
- }
- return bOverload;
- }
- // 判定反相: 持续时间内就一个是否反相的值
- // bLastReversed:上一次的反相,如果反相不明显时,维持上一次的反相
- void OneSecondData::CalcPhase(const StVolumeParam ¶m, StPhase &phase, bool bLastReversed)
- {
- if(!param.GetPhaseSwitch()) return;
- for(int i = 0; i < VOLUME_INFO_NUM; ++i)
- {
- if(aryPhase[i] < param.GetPhaseThreshold())
- {
- ++phase.iReversedNum;
- }
- else
- {
- /*************************************************************
- * 金海林加入
- * 时间: 2017年1月6日 13:42:47
- * 描述: bLastReversed:上一次的反相,如果反相不明显时,维持上一次的反相
- *************************************************************/
- //int nThreshold = 0 - param.GetPhaseThreshold();
- float nThreshold = GInfo.ignorePhaseThreshold();
- if (param.GetPhaseThreshold() < 0 && nThreshold >= 0)
- {
- if (aryPhase[i] < nThreshold && bLastReversed)
- {
- ++phase.iReversedNum;
- }
- else
- {
- ++phase.iUnReversedNum;
- }
- }
- else
- /**********金海林加入结束*************/
- ++phase.iUnReversedNum;
- }
- }
- }
- // 判定反相: 每秒都有一个是否反相的值,持续时间内每秒都反相,就表示反相
- bool OneSecondData::CalcPhaseOneSecond(const StVolumeParam ¶m, bool bLastReversed)
- {
- if(!param.GetPhaseSwitch()) return false;
- StPhase phase;
- CalcPhase(param, phase, bLastReversed);
- int iRate = phase.iReversedNum * 100;
- int nNum = param.GetPhaseSensitivity() * VOLUME_INFO_NUM;
- // 反相灵敏度
- return iRate > nNum;
- }
- /* 判断是否是固定的音量 */
- bool OneSecondData::isConstDB(int &nLeftDB, int &nRightDB)
- {
- nLeftDB = aryLeftDB[0];
- nRightDB = aryRightDB[0];
- int nLeftNum = 0;
- int nRightNum = 0;
- for(int i = 1; i < VOLUME_INFO_NUM; ++i)
- {
- if (aryLeftDB[i] == nLeftDB)
- {
- ++nLeftNum;
- }
- if (aryRightDB[i] == nRightDB)
- {
- ++nRightNum;
- }
- }
- // 30个值里面有25个以上是一样的,就表示固定音频
- const int nMinNum = GInfo.sinEffectiveNum();
- if (nLeftNum >= nMinNum && nRightNum >= nMinNum)
- {
- return true;
- }
- return false;
- }
- /*-------------------------------------------------------------------------------
- * AudioSrcData
- *-------------------------------------------------------------------------------*/
- AudioSrcData::AudioSrcData(int32_t recordSize)
- {
- totalSize = recordSize > 0 ? recordSize : 192000; // 默认大小为192000字节(1秒的48kHz采样率,16位深度,双声道)
- dataSize = 0;
- pData = new char[totalSize] {0}; // 初始化为0
- }
- AudioSrcData::AudioSrcData(const AudioSrcData& obj)
- {
- *this = obj; // 使用赋值运算符进行深拷贝
- }
- AudioSrcData& AudioSrcData::operator=(const AudioSrcData &obj)
- {
- if(this == &obj)
- {
- return *this; // 防止自赋值
- }
- if(pData != nullptr)
- {
- delete [] pData;
- pData = nullptr;
- }
- dataSize = obj.dataSize;
- totalSize = obj.totalSize;
- startTime = obj.startTime;
- endTime = obj.endTime;
- pData = new char[totalSize];
- if (pData == nullptr)
- {
- SPDLOG_ERROR("CRecordData::operator= memory allocation failed, size: {}", totalSize);
- return *this; // 分配失败,返回当前对象
- }
- memcpy(pData, obj.pData, obj.dataSize);
- return *this;
- }
- // AudioSrcData::AudioSrcData(AudioSrcData&& obj)
- // {
- // if(obj.pData == nullptr)
- // {
- // return;
- // }
- // if(pData != nullptr)
- // {
- // delete [] pData;
- // pData = nullptr;
- // }
- // dataSize = obj.dataSize;
- // totalSize = obj.totalSize;
- // pData = obj.pData;
- // dateTime = obj.dateTime;
- // obj.pData = nullptr; // 避免析构时删除
- // obj.dataSize = 0; // 清空数据大小,避免误用
- // obj.totalSize = 0; // 清空总大小,避免误用
- // obj.dateTime = QDateTime(); // 清空开始时间戳
- // return;
- // }
- // void AudioSrcData::operator=(AudioSrcData&& obj)
- // {
- // if(this == &obj)
- // {
- // return; // 防止自赋值
- // }
- // if(obj.pData == nullptr)
- // {
- // return;
- // }
- // if(pData != nullptr)
- // {
- // delete [] pData;
- // pData = nullptr;
- // }
- // dataSize = obj.dataSize;
- // totalSize = obj.totalSize;
- // pData = obj.pData;
- // dateTime = obj.dateTime;
- // obj.pData = nullptr; // 避免析构时删除
- // obj.dataSize = 0; // 清空数据大小,避免误用
- // obj.totalSize = 0; // 清空总大小,避免误用
- // obj.dateTime = QDateTime(); // 清空开始时间戳
- // return;
- // }
- AudioSrcData::~AudioSrcData()
- {
- if(pData != nullptr)
- {
- delete [] pData;
- }
- }
- /* 分配内存空间 */
- bool AudioSrcData::allocateMemory(int32_t size)
- {
- if(pData != nullptr)
- {
- delete [] pData; // 释放之前的内存
- pData = nullptr;
- }
- if(size == 0)
- {
- SPDLOG_ERROR("AudioSrcData::allocateMemory size is 0");
- return false;
- }
- totalSize = size;
- dataSize = 0;
- pData = new char[totalSize] {0};
- if(pData == nullptr)
- {
- SPDLOG_ERROR("AudioSrcData::allocateMemory memory allocation failed, size: {}", totalSize);
- return false;
- }
- startTime = QDateTime();
- endTime = QDateTime();
- return true;
- }
- /* 置零 */
- void AudioSrcData::clear()
- {
- if(pData != nullptr)
- {
- memset(pData, 0, totalSize); // 清空数据
- }
- dataSize = 0; // 重置数据大小
- startTime = QDateTime(); // 重置开始时间戳
- endTime = QDateTime(); // 重置结束时间戳
- }
- /* 添加数据,返回添加的数据长度 */
- int32_t AudioSrcData::appendData(const char* srcData, int32_t size)
- {
- if(srcData == nullptr || size == 0)
- {
- SPDLOG_ERROR("AudioSrcData::appendData srcData is null or size is 0");
- return 0; // 无效数据
- }
- if(pData == nullptr)
- {
- pData = new char[totalSize];
- if(pData == nullptr)
- {
- SPDLOG_ERROR("AudioSrcData::appendData memory allocation failed, size: {}", totalSize);
- return 0; // 内存分配失败
- }
- }
- int32_t copySize = std::min(size, totalSize - dataSize);
- memcpy(pData + dataSize, srcData, copySize);
- dataSize += copySize;
- return copySize;
- }
- /*--------------------------------------------------------------
- * AudioLeftRightData
- *--------------------------------------------------------------*/
- AudioLeftRightData::AudioLeftRightData(int totalSize)
- {
- if (totalSize == 0)
- {
- SPDLOG_ERROR("AudioLeftRightData::AudioLeftRightData totalSize is 0");
- return;
- }
- this->totalSize = totalSize;
- vecLeftData.reserve(totalSize);
- vecRightData.reserve(totalSize);
- startTime = QDateTime();
- endTime = QDateTime();
- numMSecond = 0;
- }
- AudioLeftRightData::~AudioLeftRightData()
- {
-
- }
- AudioLeftRightData::AudioLeftRightData(const AudioLeftRightData& obj)
- {
- *this = obj; // 使用赋值运算符进行深拷贝
- }
- AudioLeftRightData& AudioLeftRightData::operator=(const AudioLeftRightData &obj)
- {
- if (this == &obj)
- {
- return *this; // 防止自赋值
- }
- // 释放原有资源
- vecLeftData.clear();
- vecRightData.clear();
- // 复制数据
- totalSize = obj.totalSize;
- vecLeftData = obj.vecLeftData;
- vecRightData = obj.vecRightData;
- // 复制时间戳
- startTime = obj.startTime;
- endTime = obj.endTime;
- numMSecond = obj.numMSecond;
- return *this;
- }
- /* 判断是否是同一个数据,通过数据大小和时间戳来判断 */
- bool AudioLeftRightData::isSameData(const AudioLeftRightData& obj) const
- {
- return (totalSize == obj.totalSize && startTime == obj.startTime && endTime == obj.endTime &&
- vecLeftData == obj.vecLeftData && vecRightData == obj.vecRightData);
- }
- /*--------------------------------------------------------------
- * WavFilePath数据
- *--------------------------------------------------------------*/
- WavFilePath& WavFilePath::operator=(const WavFilePath& obj)
- {
- if (this == &obj)
- {
- return *this; // 防止自赋值
- }
- fileName = obj.fileName;
- startDateTime = obj.startDateTime;
- endDateTime = obj.endDateTime;
- return *this;
- }
- bool WavFilePath::operator==(const WavFilePath& obj) const
- {
- return (fileName == obj.fileName &&
- startDateTime == obj.startDateTime &&
- endDateTime == obj.endDateTime);
- }
|