123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #ifndef _AUDIODATA_H_
- #define _AUDIODATA_H_
- #include <QString>
- #include <QDateTime>
- #include <qdatetime.h>
- #include <vector>
- #include "GlobalVariable.h"
- #include "ChannelParam.h"
- /* =========================================================================================
- * WAV文件头信息结构体及其功能函数
- * =========================================================================================*/
- #pragma pack(1)
- /**
- * @brief Wav头信息
- *
- */
- struct WavHeader
- {
- char RIFF[4] = {'R', 'I', 'F', 'F'}; /* RIFF标识符 */
- uint64_t fileSize = 0; // 文件大小
- char WAVE[4] = {'W', 'A', 'V', 'E'}; // WAVE标识符
- char fmt[4] = {'f', 'm', 't', ' '}; // fmt子块标识符
- uint32_t fmtChunkSize = 16; // fmt子块大小
- uint16_t audioFormat = 1; // 音频格式,1表示PCM
- uint16_t numChannels = 2; // 声道数,1表示单声道,2表示立体声
- uint32_t sampleRate = 48000; // 采样率
- uint32_t byteRate = 0; // 字节率,等于采样率 * 声道数 * 每个采样点的字节数
- uint16_t blockAlign = 4; // 块对齐,等于声道数 * 每个采样点的字节数
- uint16_t bitsPerSample = 16; // 每个采样点的位数,16位深度
- char data[4] = {'d', 'a', 't', 'a'}; // data子块标识符
- uint32_t dataChunkSize = 0; // 数据块大小,等于音频数据的字节数
- /* 一些需要手动设置的参数 */
- void setSampleRate(uint32_t rate) { sampleRate = rate; }
- void setNumChannels(uint16_t channels) { numChannels = channels; }
- void setBitsPerSample(uint16_t bits) { bitsPerSample = bits; }
- void setDataSize(uint32_t size) { dataChunkSize = size; }
- /* 计算一些其他需要计算的数据 */
- void calculateDerivedFields()
- {
- byteRate = sampleRate * numChannels * (bitsPerSample / 8);
- blockAlign = numChannels * (bitsPerSample / 8);
- fileSize = sizeof(WavHeader) - 8 + dataChunkSize; // 文件大小 = 头部大小 - 8 + 数据块大小
- }
- };
- #pragma pack()
- /* 修改wav文件已写入的大小 */
- bool modifyWavFileHeader(const QString& fileName, WavHeader& header);
- /* 修改录音文件名 */
- bool modifyFileName(const QString& fileName, const QString& newFileName);
- /* =========================================================================================
- * 其他数据结构
- * =========================================================================================*/
- // 反相数结构
- struct StPhase
- {
- StPhase() : iReversedNum(0), iUnReversedNum(0) {}
- StPhase(const StPhase& obj) { *this = obj; }
- // 1秒钟内的反相数
- int iReversedNum;
- // 1秒钟内的非反相数
- int iUnReversedNum;
- int GetPhaseNum() { return iReversedNum + iUnReversedNum; }
- StPhase& operator=(const StPhase& obj)
- {
- iReversedNum = obj.iReversedNum;
- iUnReversedNum = obj.iUnReversedNum;
- return *this;
- }
- };
- // 一秒钟的数据
- struct OneSecondData
- {
- OneSecondData();
- ~OneSecondData();
- OneSecondData(const OneSecondData& obj);
- OneSecondData& operator=(const OneSecondData &obj);
- void Init();
- // 音频是否有错误
- // bool AudioLeftRightDiff();
- // 判定静音
- int calSilentDB(const StVolumeParam ¶m);
- bool CalcDBOneSecond(const StVolumeParam ¶m);
-
- // 判定过载
- int CalcOverload(const StVolumeParam ¶m);
- bool CalcOverloadOneSecond(const StVolumeParam ¶m);
- // 判定反相: 持续时间内就一个是否反相的值
- // bLastReversed:上一次的反相,如果反相不明显时,维持上一次的反相
- void CalcPhase(const StVolumeParam ¶m, StPhase &phase, bool bLastReversed);
- // 判定反相: 每秒都有一个是否反相的值,持续时间内每秒都反相,就表示反相
- bool CalcPhaseOneSecond(const StVolumeParam ¶m, bool bLastReversed);
- /* 判断是否是固定的音量 */
- bool isConstDB(int &nLeftDB, int &nRightDB);
- // // 打印输出
- // void OutPutVolumeInfo(QString strHeader);
- // void OutPutVolumeInfoEx(QString strHeader, CShowCmdLog &logFile);
-
- public:
- int nAudioError;
- // 一个音量包有30个DB
- int aryLeftDB[VOLUME_INFO_NUM];
- int aryRightDB[VOLUME_INFO_NUM];
- // 相位值列表
- float aryPhase[VOLUME_INFO_NUM];
- QDateTime startTime; /* 开始时间戳 */
- QDateTime endTime; /* 结束时间戳 */
- };
- /**
- * @brief 音频原始数据
- *
- */
- struct AudioSrcData
- {
- public:
- AudioSrcData(uint32_t recordSize = 0);
-
- AudioSrcData(const AudioSrcData& obj);
- AudioSrcData& operator=(const AudioSrcData &obj);
- AudioSrcData(AudioSrcData&& obj) = delete;
- void operator=(AudioSrcData&& obj) = delete;
- ~AudioSrcData();
- /* 分配内存空间 */
- bool allocateMemory(uint32_t size);
- /* 置零 */
- void clear();
- /* 添加数据,返回添加的数据长度 */
- uint32_t appendData(const char* srcData, uint32_t size);
- /* 返回是数据否满了 */
- bool isFull() const { return (dataSize >= totalSize); }
- /* 判断是否为空 */
- bool isEmpty() const { return (dataSize == 0); }
- char *pData = nullptr; /* 数据缓存 */
- uint32_t totalSize = 0; /* 总长度 */
- uint32_t dataSize = 0; /* 有效数据长度 */
- QDateTime startTime; /* 数据时间戳,开始时间 */
- QDateTime endTime; /* 数据时间戳,结束时间 */
- private:
-
- };
- /**
- * @brief 存储左右声道的数据
- *
- */
- struct AudioLeftRightData
- {
- AudioLeftRightData(int totalSize);
- ~AudioLeftRightData();
- AudioLeftRightData(const AudioLeftRightData& obj);
- AudioLeftRightData& operator=(const AudioLeftRightData &obj);
- /* 判断是否是同一个数据,通过数据大小和时间戳来判断 */
- bool isSameData(const AudioLeftRightData& obj) const;
-
- /* 音频数据 */
- std::vector<double> vecLeftData; /* 左声道数据 */
- std::vector<double> vecRightData; /* 右声道数据 */
- int totalSize = 0; /* 总长度,两个声道的总长度是一样的 */
- int numMSecond = 0; /* 数据对应的毫秒数 */
- QDateTime startTime; /* 开始时间戳 */
- QDateTime endTime; /* 结束时间戳 */
- };
- /**
- * @brief 存储wav小文件路径的结构体
- *
- */
- struct WavFilePath
- {
- std::string fileName; /* 文件路径 */
- QDateTime startDateTime; /* 开始时间戳 */
- QDateTime endDateTime; /* 结束时间戳 */
- WavFilePath() = default;
- WavFilePath& operator=(const WavFilePath& obj);
- bool operator==(const WavFilePath& obj) const;
- };
- #endif // _AUDIODATA_H_
|