当前位置: 首页> 游戏> 手游 > 成都企业网站设计制作_爱站网关键词挖掘工具站长工具_足球世界排名国家最新_重庆疫情最新情况

成都企业网站设计制作_爱站网关键词挖掘工具站长工具_足球世界排名国家最新_重庆疫情最新情况

时间:2025/7/9 17:26:59来源:https://blog.csdn.net/Hellomino_/article/details/145698093 浏览次数:0次
成都企业网站设计制作_爱站网关键词挖掘工具站长工具_足球世界排名国家最新_重庆疫情最新情况

 对于wav的采样格式讨论较多的是定浮点采样

基于上一节我们对采样点的理解

车载音频开发(二):对音频数据作音量调节_音频数据的音量控制代码-CSDN博客

定点常见的有16bit,24bit,和32bit

浮点一般用float (32bit) IEEE 754浮点数

不同位深度的取值范围:

       16bit 定点数:  -32,768 ~ 32,767

       24bit 定点数:  -8,388,608 ~ 8,388,607

       32bit 定点数:  -2,147,483,648 ~ 2,147,483,647

       IEEE 浮点数:  [-3.4*10^38, -1.18*10^-38] ∪ [1.18*10^-38, 3.4 * 10^38]

       对于不论多少位的定点采样,通常都要将其转换为浮点数(归一化)对其进行处理,且在wav定点采样存储时,数值超过1或小于-1的值通常无意义,即不论多少位的定点采样,在转换至浮点时,其值不能超过1,且不能小于-1;

      以下是定点转浮点的转换关系表:

转化前16bit-32,768……32,767
24bit-8,388,608……8,388,607
32bit-2,147,483,648……2,147,483,647
……
转化后浮点数-1……1

        当浮点转定点时,若数值在-1到1的范围内,乘上所要转换的位深度的最大取值;当数值超过1或小于-1时,通常会把大于1或者小于-1的数直接赋值为1或-1;

知道这些我就可以开始创作我们的代码了:

     

   wav.h

//wav.h
#pragma once
#ifndef __Wav_h__
#define __Wav_h__
#include <vector>
#include <string>
#include <iostream>using namespace std;
const double PI = 3.14159265358979323846;#ifndef M_PI
#define M_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406
#endif#ifndef  WAV___
#define  WAV___
class wav {vector<char> buffer;vector<char> Peak_buffer;     // Peakvector<float> data_ford;vector<size_t> channel_sizes;struct WavHeader {char chunkId[4] = { 'R','I','F','F' };	    //"RIFF"uint32_t chunkSize = 0;			            //totalsize - 8char format[4] = { 'R','I','F','F' };	    //"WAVE"char subchunk1Id[4] = { 'f','m','t',' ' };	//"fmt"uint32_t subchunk1Size = 16;		        //16:Normal; 18:Non_PCM; 40:Extensible;}headera;struct type40_header {uint16_t audioFormat = 1; 		    //wav 格式 1;int型  3:float型  65534:未知uint16_t numChannels = 1; 		    //声道数 uint32_t sampleRate = 48000;		//采样率uint32_t byteRate = 48000;			//比特率:采样率 * 采样位宽uint16_t blockAlign = 2;		    //采样深度:uint16_t bitsPerSample = 16;		//采样位宽:采样深度 * 8uint16_t cbSize;uint16_t wValidBitsPerSample;uint32_t dwChannelMask;char SubFormat[4];char ckID[4];uint32_t cksize;uint32_t dwSampleLength;}headerb;struct data_header {char subchunk2Id[4] = { 'd','a','t','a' };	//"data"uint32_t subchunk2Size = 0;		            //datasize}headerc;// 定义fact块结构struct FactChunk {char fact_id[4] = { 'f','a','c','t' };  // "fact"uint32_t fact_size = 4;       // fact块大小uint32_t sample_length;   // 未压缩的样本数}headerd;// 定义fact块结构struct PeakChunk {char Peak_id[4] = { 'P','E','A','K' };  // "fact"uint32_t Peak_size = 4;       // fact块大小}headere;int fact_flag = 0;int Peak_flag = 0;public:string filename;string filepath;int flag = 0;wav(const string& filename);//查看头部数据int header_check();int data_check();void free();
};
#endif // ! WAVstruct WavHeader {char chunkId[4];			//"RIFF"uint32_t chunkSize;			//totalsize - 8char format[4];				//"WAVE"char subchunk1Id[4];		//"fmt"uint32_t subchunk1Size;		//16:Normal; 18:Non_PCM; 40:Extensible;
};struct type40_header {uint16_t audioFormat; 		//wav 格式 1;int型  3:float型  65534:未知uint16_t numChannels; 		//声道数 uint32_t sampleRate;		//采样率uint32_t byteRate;			//比特率:采样率 * 采样位宽uint16_t blockAlign;		//采样深度:uint16_t bitsPerSample;		//采样位宽:采样深度 * 8uint16_t cbSize;uint16_t wValidBitsPerSample;uint32_t dwChannelMask;char SubFormat[4];char ckID[4];uint32_t cksize;uint32_t dwSampleLength;
};struct data_header {char subchunk2Id[4];		//"data"uint32_t subchunk2Size;		//datasize
};int switch_blockAlign(const char* inputfile, int cmd, const string& outputfile);#endif

wav.cpp

//wav.c
#include <fstream>
#include "wav.h"
#include "Filter.h"wav::wav(const string& filename) {ifstream inputFile(filename, ios::binary);if (!inputFile.is_open()) {cerr << "无法打开文件" << endl;this->flag = -1;return;}inputFile.read(reinterpret_cast<char*>(&this->headera), sizeof(this->headera));inputFile.read(reinterpret_cast<char*>(&this->headerb), this->headera.subchunk1Size);inputFile.read(reinterpret_cast<char*>(&this->headerc), sizeof(this->headerc));string data = this->headerc.subchunk2Id;data.resize(4);if (data != "data"){this->fact_flag = 1;memcpy(this->headerd.fact_id, this->headerc.subchunk2Id, 4);//printf("fact_id   : ,%c%c%c%c\n", this->headerd.fact_id[0], this->headerd.fact_id[1], this->headerd.fact_id[2], this->headerd.fact_id[3]);this->headerd.fact_size = this->headerc.subchunk2Size;//cout << "fact_size : ," << this->headerd.fact_size << endl;inputFile.read(reinterpret_cast<char*>(&this->headerd.sample_length), this->headerc.subchunk2Size);//cout << "sample_length : ," << this->headerd.sample_length << endl;inputFile.read(reinterpret_cast<char*>(&this->headerc), sizeof(this->headerc));data = this->headerc.subchunk2Id;data.resize(4);}if (data != "data"){this->Peak_flag = 1;memcpy(this->headere.Peak_id, this->headerc.subchunk2Id, 4);// printf("PEAK_id   : ,%c%c%c%c\n", this->headere.Peak_id[0], this->headere.Peak_id[1], this->headere.Peak_id[2], this->headere.Peak_id[3]);this->headere.Peak_size = this->headerc.subchunk2Size;//cout << "PEAK_size : ," << this->headere.Peak_size << endl;this->Peak_buffer.resize(this->headerc.subchunk2Size);inputFile.read(this->Peak_buffer.data(), this->headere.Peak_size);inputFile.read(reinterpret_cast<char*>(&this->headerc), sizeof(this->headerc));data = this->headerc.subchunk2Id;}this->filepath = filename;this->filename = filename.substr(filename.rfind("\\") + 1, filename.size());this->buffer.resize(this->headerc.subchunk2Size);inputFile.read(this->buffer.data(), this->headerc.subchunk2Size);this->buffer.resize(this->headerc.subchunk2Size);fflush(stdout);inputFile.close();
}void wav::free()
{this->buffer.clear();this->data_ford.clear();this->Peak_buffer.clear();this->filename.clear();this->filepath.clear();}//查看头部数据
int wav::header_check() {//printf("\ntotalsize : \t%u \n", header.chunkSize + 8);printf("chunkId       : ,%c%c%c%c\n", this->headera.chunkId[0], this->headera.chunkId[1], this->headera.chunkId[2], this->headera.chunkId[3]);cout << "chunkSize     : ," << this->headera.chunkSize << endl;printf("format        : ,%c%c%c%c\n", this->headera.format[0], this->headera.format[1], this->headera.format[2], this->headera.format[3]);printf("subchunk1Id   : ,%c%c%c%c\n", this->headera.subchunk1Id[0], this->headera.subchunk1Id[1], this->headera.subchunk1Id[2], this->headera.subchunk1Id[3]);cout << "subchunk1Size : ," << this->headera.subchunk1Size << endl;cout << "audioFormat   : ," << this->headerb.audioFormat << endl;cout << "numChannels   : ," << this->headerb.numChannels << endl;cout << "sampleRate    : ," << this->headerb.sampleRate << endl;cout << "byteRate      : ," << this->headerb.byteRate << endl;cout << "blockAlign    : ," << this->headerb.blockAlign << endl;cout << "bitsPerSample : ," << this->headerb.bitsPerSample << endl;if (65534 == this->headerb.audioFormat){cout << "cbSize        : ," << this->headerb.cbSize << endl;cout << "wValidBitsPerSample: ," << this->headerb.wValidBitsPerSample << endl;cout << "dwChannelMask : ," << this->headerb.dwChannelMask << endl;printf("SubFormat     : ,%02X %02X %02X %02X\n", this->headerb.SubFormat[0], this->headerb.SubFormat[1], this->headerb.SubFormat[2], this->headerb.SubFormat[3]);printf("ckID          : ,%02X %02X %02X %02X\n", this->headerb.ckID[0], this->headerb.ckID[1], this->headerb.ckID[2], this->headerb.ckID[3]);cout << "cksize        : ," << this->headerb.cksize << endl;cout << "dwSampleLength: ," << this->headerb.dwSampleLength << endl;}if (fact_flag) {printf("fact_id   : ,%c%c%c%c\n", this->headerd.fact_id[0], this->headerd.fact_id[1], this->headerd.fact_id[2], this->headerd.fact_id[3]);cout << "fact_size : ," << this->headerd.fact_size << endl;cout << "sample_length : ," << this->headerd.sample_length << endl;if (Peak_flag){//memcpy(this->headere.Peak_id, this->headerc.subchunk2Id, 4);printf("PEAK_id   : ,%c%c%c%c\n", this->headere.Peak_id[0], this->headere.Peak_id[1], this->headere.Peak_id[2], this->headere.Peak_id[3]);//this->headere.Peak_size = this->headerc.subchunk2Size;cout << "PEAK_size : ," << this->headere.Peak_size << endl;cout << "PEAK_DATA   : ," << endl;for (int i = 0; i < this->headere.Peak_size; i++) {printf(" %02X ,", (uint8_t)this->Peak_buffer[i]);}cout << endl;}}printf("subchunk2Id   : ,%c%c%c%c\n", this->headerc.subchunk2Id[0], this->headerc.subchunk2Id[1], this->headerc.subchunk2Id[2], this->headerc.subchunk2Id[3]);cout << "subchunk2Size : ," << this->headerc.subchunk2Size << endl;return 0;
}
#define __PRINTF
int wav::data_check() {const size_t dataSize = this->headerc.subchunk2Size;uint16_t perdatasize = this->headerb.bitsPerSample / 8;int channels = this->headerb.numChannels;this->data_ford.resize(dataSize);
#ifdef __MAXDATAthis->maxdata.resize(this->headerb.numChannels);
#endiffloat wavdata = 0.0;int32_t Wavdata = 0;int16_t Wavdata16 = 0;#ifdef __SPRINTF_Sstring csv;char sam[1024] = {};csv += ",";for (int j = 0; j < headera.numChannels; j++) {sprintf_s(sam, "channel[%d] , ,", j + 1);csv += sam;}csv += ("\ndata,");for (int j = 0; j < headera.numChannels; j++) {csv += ("Frequency , Response ,");}csv += "\n";
#endifsize_t each_size = dataSize / perdatasize / channels;for (size_t i = 0; i < each_size; i++) {#ifdef __SPRINTF_Ssprintf_s(sam, "data[%8d] : ,", (unsigned int)i);csv += sam;
#endiffor (size_t j = 0; j < channels; j++) {if (16 == this->headerb.bitsPerSample){memcpy(&Wavdata16, (this->buffer).data() + i * channels * perdatasize + j * perdatasize, perdatasize);wavdata = (float)Wavdata16 / 32768;
#ifdef __PRINTFprintf(" %10d , %.2f db ,", Wavdata16, 20 * log10f(abs((float)Wavdata16) / 32768));
#endif
#ifdef __SPRINTF_Ssprintf_s(sam, " %10d , %.2f db ,", Wavdata16, 20 * log10f(abs((float)Wavdata16) / 32768));
#endif}else if (24 == this->headerb.bitsPerSample){memcpy(&Wavdata, (this->buffer).data() + i * channels * perdatasize + j * perdatasize, perdatasize);wavdata = (float)(Wavdata << 8) / 256 / 8388608;
#ifdef __PRINTFprintf(" %10d , %.2f db ,", (Wavdata << 8) / 256, 20 * log10f(abs((float)(Wavdata << 8)) / 256 / 8388608));
#endif
#ifdef __SPRINTF_Ssprintf_s(sam, " %10d , %.2f db ,", (Wavdata << 8) / 256, 20 * log10f(abs((float)(Wavdata << 8)) / 256 / 8388608));
#endif   }else if (32 == this->headerb.bitsPerSample){if (3 == this->headerb.audioFormat || (65534 == this->headerb.audioFormat && 0x03 == this->headerb.SubFormat[0])) {memcpy(&wavdata, (this->buffer).data() + i * channels * perdatasize + j * perdatasize, perdatasize);
#ifdef __PRINTFprintf(" %.6f , %.2f db ,", wavdata, 20 * log10f(abs(wavdata)));
#endif
#ifdef __SPRINTF_Ssprintf_s(sam, " %.8f , %.2f db ,", wavdata, 20 * log10f(abs(wavdata)));
#endif }else {memcpy(&Wavdata, (this->buffer).data() + i * channels * perdatasize + j * perdatasize, perdatasize);wavdata = (float)Wavdata / 2147483648;
#ifdef __PRINTFprintf(" %16d , %.2f db ,", Wavdata, 20 * log10f(abs((float)Wavdata) / 2147483648));
#endif
#ifdef __SPRINTF_Ssprintf_s(sam, " %16d , %.2f db ,", Wavdata, 20 * log10f(abs((float)Wavdata) / 2147483648));
#endif }}if ((uint32_t)wavdata | 0) {this->data_ford[j * each_size + i] = (double)wavdata;}else{this->data_ford[j * each_size + i] = (double)wavdata;//this->data_ford[j * each_size + i] = (double)0.00000001;}#ifdef __MAXDATAthis->maxdata[j] = this->maxdata[j] >= wavdata ? this->maxdata[j] : wavdata;
#endif
#ifdef __SPRINTF_Scsv += sam;
#endif}
#ifdef __PRINTFcout << endl;
#endif
#ifdef __SPRINTF_Scsv += "\n";
#endif}//this->buffer.clear();//inputFile.close();
#ifdef __SPRINTF_Sofstream out;string outfile = this->filename.substr(0, filename.rfind(".") + 1) + "csv";out.open(outfile);out.flush();out << csv;out.close();cout << "\ndatas save at " << outfile << endl;
#endifreturn 0;
}static inline int32_t clamp32_from_float(float f)
{static const float scale = (float)(1UL << 31);static const float limpos = 1.;static const float limneg = -1.;if (f <= limneg) {return INT32_MIN;}else if (f >= limpos) {return INT32_MAX;}f *= scale;/* integer conversion is through truncation (though int to float is not).* ensure that we round to nearest, ties away from 0.*/return f > 0 ? f + 0.5 : f - 0.5;
}static inline float float_from_i32(int32_t ival)
{static const float scale = 1. / (float)(1UL << 31);return ival * scale;
}int switch_blockAlign(const char* inputfile, int cmd, const string& outputfile)
{WavHeader header = {};type40_header headera = {};data_header headerb = {};//header_check(inputfile);ifstream input(inputfile, ios::binary);if (!input.is_open()) {cerr << "无法打开文件" << endl;return -1;}// 读取WAV文件头部信息并写入ofstream output(outputfile, ios::binary);if (!output.is_open()) {cerr << "无法打开文件" << endl;return -1;}uint32_t rearsize = 0;input.read(reinterpret_cast<char*>(&header), sizeof(header));input.read(reinterpret_cast<char*>(&headera), header.subchunk1Size);input.read(reinterpret_cast<char*>(&headerb), sizeof(headerb));uint16_t oldperdata = headera.bitsPerSample;uint16_t Format = headera.audioFormat;if (5 == cmd) {headera.bitsPerSample = 8 * 4;headera.audioFormat = 3;}else {headera.bitsPerSample = 8 * cmd;headera.audioFormat = 1;}const size_t dataSize = headerb.subchunk2Size;headerb.subchunk2Size = headerb.subchunk2Size / oldperdata * headera.bitsPerSample;headera.blockAlign = headera.bitsPerSample / 8 * headera.numChannels;headera.byteRate = headera.blockAlign * headera.sampleRate;rearsize = header.chunkSize - (uint32_t)dataSize - header.subchunk1Size - sizeof(headerb) - 12;header.chunkSize = header.chunkSize + headerb.subchunk2Size - (uint32_t)dataSize;output.write(reinterpret_cast<char*>(&header), sizeof(header));output.write(reinterpret_cast<char*>(&headera), header.subchunk1Size);output.write(reinterpret_cast<char*>(&headerb), sizeof(headerb));vector<char> outputBuffer(headerb.subchunk2Size);vector<char> buffer(dataSize);input.read(buffer.data(), dataSize);vector<char> rear(rearsize);input.read(rear.data(), rear.size());input.close();// 读取WAV文件头部信息并写入uint16_t perdatasize = oldperdata / 8;uint16_t perdatasize1 = headera.bitsPerSample / 8;float wavdata = 0;int32_t WavData32 = 0;int32_t WavData24 = 0;int16_t WavData16 = 0;// 复制数据到20个通道for (size_t i = 0; i < dataSize / perdatasize; i++) {switch (oldperdata) {case 16:memcpy(&WavData16, buffer.data() + i * perdatasize, perdatasize);//printf(" data[%d]:\t%10d \t %f db \n", (int)i, WavDate16, 20 * log10f(abs((float)WavDate16) / 32768));WavData32 = WavData16 * 256 * 256;wavdata = (float)WavData16 / 32768;break;case 24:memcpy(&WavData24, buffer.data() + i * perdatasize, perdatasize);//printf(" data[%d]:\t%10d \t %f db \n", (int)i, (WavDate32 << 8) / 256, 20 * log10f(abs((float)(WavDate32 << 8)) / 256 / 8388608));wavdata = (float)(WavData24 << 8) / 256 / 8388608;WavData32 = WavData24 << 8;break;case 32:if (1 == Format) {memcpy(&WavData32, buffer.data() + i * perdatasize, perdatasize);//printf(" data[%d]:\t%.16f \t %f db \n", (int)i, wavdate, 20 * log10f(abs(wavdate)));wavdata = float_from_i32(WavData32);}else {memcpy(&wavdata, buffer.data() + i * perdatasize, perdatasize);//printf(" data[%d]:\t%16d \t %f db \n", (int)i, WavDate32, 20 * log10f(abs((float)WavDate32) / 2147483648));WavData32 = clamp32_from_float(wavdata);}break;}switch (cmd){case 2:WavData16 = WavData32 / 256 / 256;memcpy(&outputBuffer.data()[i * perdatasize1], &WavData16, perdatasize1);break;case 3:WavData24 = WavData32 / 256;memcpy(&outputBuffer.data()[i * perdatasize1], &WavData24, perdatasize1);break;case 4:memcpy(&outputBuffer.data()[i * perdatasize1], &WavData32, perdatasize1);break;case 5:memcpy(&outputBuffer.data()[i * perdatasize1], &wavdata, perdatasize1);}}// 写入数据到输出文件的各通道input.close();output.write(outputBuffer.data(), outputBuffer.size());output.write(rear.data(), rear.size());output.close();cout << "****************************************************" << endl;wav outputwav(outputfile);outputwav.header_check();return 0;
}

  wavBitConversion.cpp

//wavBitConversion.cpp
#include <fstream>
#include "wav.h"void user_usage()
{//printf("/*********************************************************************************\n");printf("\nuser usage : \n");printf("  Convert WAV file bit depth:\n    wavBitConversion.exe [options] input.wav \n");printf("options : \n");printf("  -int16 :  Convert WAV file bit depth to int16 type\n");printf("  -int24 :  Convert WAV file bit depth to int24 type\n");printf("  -int32 :  Convert WAV file bit depth to int32 type\n");printf("  -f32   :  Convert WAV file bit depth to float32 type\n");//printf("*********************************************************************************/\n");}int work(const char* op, const char* file) {int flag = 0;string num_str;string cmd = op;if (cmd == "-int16"){cout << "  options : -int16 " << endl << endl;flag = 2;num_str = "bitint16_from_";}else if (cmd == "-int24"){cout << "  options : -int24 " << endl << endl;flag = 3;num_str = "bitint24_from_";}else if (cmd == "-int32"){cout << "  options : -int32 " << endl << endl;flag = 4;num_str = "bitint32_from_";}else if (cmd == "-f32"){cout << "  options : -f32 " << endl << endl;flag = 5;num_str = "bitf32_from_";}else {cerr << "Error : option is observe" << endl;return -1;}string filename = file;if (filename.size() < 4 || filename.rfind(".") == std::string::npos || filename.substr(filename.rfind("."), filename.size())!= ".wav") {cerr << "Error : input.wav is observe  >>>>>>> "  << filename << endl;return -1;}wav wav1(filename);if( wav1.flag ) {cerr << "Error : input.wav is observe  >>>>>>> " << filename << endl;return -1;}wav1.header_check();if (1 < flag && 6 > flag) {switch_blockAlign(file, flag, num_str + wav1.filename);cout << endl << "转换成功 :" << num_str + wav1.filename << endl << endl;}return 0;
}int main(int argc, const char* argv[]) {if (argc == 3 && !work(argv[1], argv[2])) {cout << endl;}else {user_usage();}return 0;
}

关键字:成都企业网站设计制作_爱站网关键词挖掘工具站长工具_足球世界排名国家最新_重庆疫情最新情况

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: