当前位置: 首页 > news >正文

DirectShow过滤器开发-写WAV音频文件过滤器

下载本过滤器DLL
本过滤器将PCM音频流,或ADPCM,IEEE_FLOAT,ALAW,MULAW,GSM610音频流写入WAV音频文件。

写WAV音频文件过滤器信息

过滤器名称:写WAV
过滤器GUID:{CF704A9C-0C67-4712-BA33-DD0AAE01A232}
DLL注册函数名:DllRegisterServer
删除注册函数名:DllUnregisterServer
过滤器有1个输入引脚。

输入引脚标识:In
输入引脚媒体类型:
主要类型:MEDIATYPE_Audio
子类型:
MEDIASUBTYPE_PCM
{0x00000002, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
MEDIASUBTYPE_IEEE_FLOAT
{0x00000006, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
{0x00000007, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
{0x00000031, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
格式类型:FORMAT_WaveFormatEx
样本为固定大小。

写WAV音频文件过滤器开发信息

WAV音频文件使用PCM方式表示音频数据,即使用short值表示采样点音频的幅值。即无压缩,也无编码;是表示音频数据最基本的方式。文件体积较大。故添加了使用压缩方式写WAV文件的方法,生成WAV文件后,Windows播放器仍可播放。

写WAV音频文件过滤器DLL的全部代码

DLL.h

#ifndef  DLL_FILE
#define DLL_FILE#include "strmbase10.h"//过滤器基础类定义文件#if _DEBUG
#pragma comment(lib, "strmbasd10.lib")//过滤器基础类实现文件调试版本
#else
#pragma comment(lib, "strmbase10.lib")//过滤器基础类实现文件发布版本
#endif// {CF704A9C-0C67-4712-BA33-DD0AAE01A232}
DEFINE_GUID(CLSID_WavWriter,//过滤器GUID0xcf704a9c, 0xc67, 0x4712, 0xba, 0x33, 0xdd, 0xa, 0xae, 0x1, 0xa2, 0x32);DEFINE_GUID(MEDIASUBTYPE_ADPCM,//0x00000002, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);DEFINE_GUID(MEDIASUBTYPE_ALAW,//0x00000006, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);DEFINE_GUID(MEDIASUBTYPE_MULAW,//0x00000007, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);DEFINE_GUID(MEDIASUBTYPE_GSM610,//0x00000031, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);#include "strsafe.h"struct WAVE_HEADER {char RIFF_ch[4] = { 'R','I','F','F' };//文件规范标识DWORD mSize = 0;//从下一项(文件类型)的开始位置,到文件的结束位置的大小,以字节为单位char WAVE_ch[4] = { 'W','A','V','E' };//文件类型char fmt_ch[4] = { 'f','m','t',' ' };//格式块标识DWORD fmt_Size = 16;//格式块大小WORD Format = 1;//编码方式WORD nChannels = 0;//声道数DWORD SampleRate = 0;//采样率DWORD ByteRate = 0;//传输率WORD BlockAlign = 0;//块对齐WORD BitsPerSample = 0;//样本位数
};class CFilter;class CPin : public CBaseInputPin
{friend class CFilter;
public:CPin(CFilter *pFilter, HRESULT *phr, LPCWSTR pPinName);~CPin();HRESULT CheckMediaType(const CMediaType *pmt);HRESULT SetMediaType(const CMediaType *pmt);STDMETHODIMP Receive(IMediaSample *pSample);HRESULT Active();HRESULT Inactive();STDMETHODIMP EndOfStream();CFilter *pCFilter;DWORD Data_Size = 0;HANDLE hFile = NULL;//输出文件句柄WORD cbSize = 0;//附加信息大小char Data_ch[4] = { 'd','a','t','a' };//数据块标识DWORD mSize = 0;//数据区块大小,以字节为单位BYTE* pAppend = NULL;
};class CFilter : public CBaseFilter, public CCritSec, public IFileSinkFilter
{friend class CPin;
public:CFilter(LPWSTR lpName, LPUNKNOWN pUnk, HRESULT *phr);virtual ~CFilter();DECLARE_IUNKNOWNSTDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);virtual HRESULT STDMETHODCALLTYPE  SetFileName(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt);virtual HRESULT STDMETHODCALLTYPE  GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt);static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);int GetPinCount();CBasePin *GetPin(int n);CPin *pCPin=NULL;   //输入引脚指针WCHAR* m_pFileName=NULL;//要创作的WAV文件路径WAVE_HEADER header;//WAV文件头
};template <class T> void SafeRelease(T** ppT)
{if (*ppT){(*ppT)->Release();*ppT = NULL;}
}#endif //DLL_FILE

DLL.cpp


#include "DLL.h"const AMOVIESETUP_MEDIATYPE InPinType[] =   // 输入引脚媒体类型
{{&MEDIATYPE_Audio,             //主要类型&MEDIASUBTYPE_PCM             //子类型},{&MEDIATYPE_Audio,             //主要类型&MEDIASUBTYPE_ADPCM           //子类型},{&MEDIATYPE_Audio,             //主要类型&MEDIASUBTYPE_IEEE_FLOAT      //子类型},{&MEDIATYPE_Audio,             //主要类型&MEDIASUBTYPE_ALAW            //子类型},{&MEDIATYPE_Audio,            //主要类型&MEDIASUBTYPE_MULAW          //子类型},{&MEDIATYPE_Audio,             //主要类型&MEDIASUBTYPE_GSM610          //子类型}
};const AMOVIESETUP_PIN sudPins[] =  // 引脚信息
{{(LPWSTR)"In",                 //引脚名称FALSE,                        //渲染引脚FALSE,                        //输出引脚FALSE,                        //具有该引脚的零个实例FALSE,                        //可以创建一个以上引脚的实例&CLSID_NULL,                  //该引脚连接的过滤器的类标识NULL,                         //该引脚连接的引脚名称6,                            //引脚支持的媒体类型数InPinType                     //媒体类型信息}
};const AMOVIESETUP_FILTER MP3Encoder =  //过滤器的注册信息
{&CLSID_WavWriter,             //过滤器的类标识L"写WAV",                     //过滤器的名称MERIT_DO_NOT_USE,             //过滤器优先值1,                            //引脚数量sudPins                       //引脚信息
};CFactoryTemplate g_Templates[] =   //类工厂模板数组
{{L"写WAV",                  //对象(这里为过滤器)名称&CLSID_WavWriter,          //对象CLSID的指针CFilter::CreateInstance,   //创建对象实例的函数的指针NULL,                      //指向从DLL入口点调用的函数的指针&MP3Encoder                //指向AMOVIESETUP_FILTER结构的指针}
};int g_cTemplates = 1;//模板数组大小STDAPI DllRegisterServer()//注册DLL
{return AMovieDllRegisterServer2(TRUE);
}STDAPI DllUnregisterServer()//删除DLL注册
{return AMovieDllRegisterServer2(FALSE);
}extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);BOOL APIENTRY DllMain(HANDLE hModule, DWORD  dwReason, LPVOID lpReserved)
{return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
}

CFilter.cpp

#include "DLL.h"CFilter::CFilter(LPWSTR lpName, LPUNKNOWN pUnk, HRESULT *phr) : CBaseFilter(lpName, pUnk, (CCritSec *) this, CLSID_WavWriter)
{pCPin = new CPin(this, phr, L"In");//创建输入引脚
}CFilter::~CFilter()
{delete[] m_pFileName; 
}CUnknown * WINAPI CFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
{return new CFilter(L"写WAV", pUnk, phr);//创建过滤器
}int CFilter::GetPinCount()
{return 1;
}CBasePin *CFilter::GetPin(int n)
{if (n != 0){return NULL;}return pCPin;
}STDMETHODIMP CFilter::NonDelegatingQueryInterface(REFIID iid, void ** ppv)
{if (iid == IID_IFileSinkFilter){return GetInterface(static_cast<IFileSinkFilter*>(this), ppv);}elsereturn CBaseFilter::NonDelegatingQueryInterface(iid, ppv);
}HRESULT CFilter::GetCurFile(LPOLESTR *ppszFileName, AM_MEDIA_TYPE *pmt)
{CheckPointer(ppszFileName, E_POINTER);*ppszFileName = NULL;if (m_pFileName != NULL){size_t len = 1 + lstrlenW(m_pFileName);*ppszFileName = (LPOLESTR)QzTaskMemAlloc(sizeof(WCHAR) * (len));if (*ppszFileName != NULL){HRESULT hr = StringCchCopyW(*ppszFileName, len, m_pFileName);}}if (pmt){ZeroMemory(pmt, sizeof(*pmt));pmt->majortype = MEDIATYPE_NULL;pmt->subtype = MEDIASUBTYPE_NULL;}return S_OK;
}HRESULT CFilter::SetFileName(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt)
{CheckPointer(pszFileName, E_POINTER);if (wcslen(pszFileName) > MAX_PATH || wcslen(pszFileName)<4)return ERROR_FILENAME_EXCED_RANGE;size_t len = 1 + lstrlenW(pszFileName);m_pFileName = new WCHAR[len];if (m_pFileName == 0)return E_OUTOFMEMORY;HRESULT hr = StringCchCopyW(m_pFileName, len, pszFileName);if (m_pFileName[len - 2] != 'v' || m_pFileName[len - 3] != 'a' || m_pFileName[len - 4] != 'w' || m_pFileName[len - 5] != '.')//如果不是WAV文件{delete[] m_pFileName; m_pFileName = NULL;return VFW_E_INVALID_FILE_FORMAT;//设置文件名失败}return S_OK;
}

CPin.cpp

#include "DLL.h"CPin::CPin(CFilter *pFilter, HRESULT *phr, LPCWSTR pPinName) : CBaseInputPin(NAME("In"), pFilter, pFilter, phr, pPinName)
{pCFilter = pFilter;}CPin::~CPin()//输入引脚析构函数
{}HRESULT CPin::CheckMediaType(const CMediaType *pmt)
{if (pmt->majortype == MEDIATYPE_Audio && pmt->formattype == FORMAT_WaveFormatEx && pmt->bFixedSizeSamples){if (pmt->subtype == MEDIASUBTYPE_PCM || pmt->subtype == MEDIASUBTYPE_ADPCM || pmt->subtype == MEDIASUBTYPE_IEEE_FLOAT|| pmt->subtype == MEDIASUBTYPE_ALAW || pmt->subtype == MEDIASUBTYPE_MULAW || pmt->subtype == MEDIASUBTYPE_GSM610)return S_OK;return S_FALSE;}elsereturn S_FALSE;
}HRESULT CPin::SetMediaType(const CMediaType *pmt)
{WAVEFORMATEX* p = (WAVEFORMATEX*)pmt->pbFormat;//给文件头参数赋值pCFilter->header.Format = p->wFormatTag;//编码方式pCFilter->header.nChannels = p->nChannels;//声道数pCFilter->header.SampleRate = p->nSamplesPerSec;//采样率pCFilter->header.ByteRate = p->nAvgBytesPerSec;;//传输率pCFilter->header.BlockAlign = p->nBlockAlign;//块对齐pCFilter->header.BitsPerSample = p->wBitsPerSample;//样本位数pCFilter->header.fmt_Size = 16;//格式块大小if (p->cbSize > 0)//如果有附加信息{cbSize = p->cbSize;pCFilter->header.fmt_Size = p->cbSize + sizeof(WAVEFORMATEX);//格式块大小if (pAppend != NULL){delete[] pAppend; pAppend = NULL;}pAppend = new BYTE[p->cbSize];if (pmt->subtype == MEDIASUBTYPE_ADPCM){BYTE info[32] = {244,7,7,0,0,1,0,0,0,2,0,255,0,0,0,0,192,0,64,0,240,0,0,0,204,1,48,255,136,1,24,255};//MEDIASUBTYPE_ADPCM附加信息CopyMemory(pAppend, &info, 32);//复制附加信息}else if (pmt->subtype == MEDIASUBTYPE_GSM610){BYTE info[2] = {64,1};CopyMemory(pAppend, &info, 2);//复制附加信息}else{CopyMemory(pAppend, pmt->pbFormat- sizeof(WAVEFORMATEX), cbSize);//复制附加信息}}return CBaseInputPin::SetMediaType(pmt);
}HRESULT CPin::Receive(IMediaSample * pSample)//接收函数
{HRESULT hr;BYTE* pBy = NULL;hr = pSample->GetPointer(&pBy);//获取引脚样本缓冲区指针long len = pSample->GetActualDataLength();//获取有效数据长度if (hFile){WriteFile(hFile, pBy, len, NULL, NULL);//写WAVE数据Data_Size += len;//记录已写数据的字节大小}return S_OK;
}HRESULT CPin::Active()
{if (pCFilter->m_pFileName == NULL){MessageBox(0, L"没有指定输出文件", L"写WAV", MB_OK); return S_FALSE;}hFile = CreateFile(pCFilter->m_pFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//创建输出文件if (INVALID_HANDLE_VALUE == hFile){MessageBox(0, L"创建输出文件失败", L"写WAV", MB_OK); return S_FALSE;}Data_Size = 0; WriteFile(hFile, &pCFilter->header, sizeof(pCFilter->header), NULL, NULL);//写WAVE文件头if (cbSize > 0)//如果有附加信息{WriteFile(hFile, &cbSize, 2, NULL, NULL);//写附加信息大小WriteFile(hFile, pAppend, cbSize, NULL, NULL);//写附加信息}WriteFile(hFile, Data_ch, 4, NULL, NULL);//写数据块标识WriteFile(hFile, &mSize, 4, NULL, NULL);//写数据块大小,写入的并非真实大小return CBaseInputPin::Active();
}HRESULT CPin::Inactive()
{LARGE_INTEGER Move; Move.QuadPart = 4;SetFilePointerEx(hFile, Move, NULL, FILE_BEGIN);//移动文件指针,到“文件大小”位置int AppendSize = pCFilter->header.fmt_Size - 16;DWORD FileSize = Data_Size + 36 + AppendSize;WriteFile(hFile, &FileSize, sizeof(FileSize), NULL, NULL);//写WAVE文件大小Move.QuadPart = 40 + AppendSize;SetFilePointerEx(hFile, Move, NULL, FILE_BEGIN);//移动文件指针,到“数据大小”位置WriteFile(hFile, &Data_Size, sizeof(Data_Size), NULL, NULL);//写WAVE数据大小CloseHandle(hFile);//关闭输出文件hFile = NULL; cbSize = 0;if (pAppend != NULL){delete[] pAppend; pAppend = NULL;}return CBaseInputPin::Inactive();
}STDMETHODIMP CPin::EndOfStream()
{pCFilter->NotifyEvent(EC_COMPLETE, S_OK, 0);return CBaseInputPin::EndOfStream();
}

下载本过滤器DLL

相关文章:

DirectShow过滤器开发-写WAV音频文件过滤器

下载本过滤器DLL 本过滤器将PCM音频流&#xff0c;或ADPCM&#xff0c;IEEE_FLOAT&#xff0c;ALAW&#xff0c;MULAW&#xff0c;GSM610音频流写入WAV音频文件。 写WAV音频文件过滤器信息 过滤器名称&#xff1a;写WAV 过滤器GUID&#xff1a;{CF704A9C-0C67-4712-BA33-DD0A…...

php根据截止时间计算剩余的时间,并且在剩余时间不足1天时仅显示小时数

//获取政策库文章public function getIndexZckList(){$fl_id = input(fl_id);if(empty(...

Docker最佳实践进阶(一):Dockerfile介绍使用

大家好,上一个系列我们使用docker安装了一系列的基础服务,但在实际开发过程中这样一个个的安装以及繁杂命令不仅仅浪费时间,更是容易遗忘,下面我们进行Docker的进阶教程,帮助我们更快速的部署和演示项目。 一、什么是Dockerfile? Dockerfile 是一个文本文件,其中包含了…...

Anything in Any Scene:无缝融入任何场景,实现逼真视频对象插入技术

人工智能咨询培训老师叶梓 转载标明出处 现实世界的视频捕获虽然因其真实性而宝贵&#xff0c;但常常受限于长尾分布的问题&#xff0c;即常见场景过度呈现&#xff0c;而关键的罕见场景却鲜有记录。这导致了所谓的"分布外问题"&#xff0c;在模拟复杂环境光线、几何…...

安卓开发中的AppCompat框架|安卓系统|安卓应用|兼容性|UI组件|核心组件|ActionBar|Fragment|最佳实践|框架|移动开发|移动应用

目录 1. 什么是AppCompat框架 1.1 AppCompat的起源 1.2 AppCompat的重要性 2. AppCompat框架的核心组件 2.1 AppCompatActivity 2.2 AppCompat主题 2.3 AppCompat Widgets 3. 在项目中使用AppCompat框架 3.1 添加依赖项 3.2 应用AppCompat主题 4. AppCompat的高级功…...

React使用useRef ts 报错

最近在写自己的React项目&#xff0c;我在使用useRef钩子函数的时候发现 TS2322: Type MutableRefObject<HTMLDivElement | undefined> is not assignable to type LegacyRef<HTMLDivElement> | undefined Type MutableRefObject<HTMLDivElement | undefined&g…...

python-信息交互-pyautogui

python-信息交互-pyautogui 一: pyautogui1> waht?2> 功能分类3> 概念及作用二: 通用功能1> function all2> function 注释三: 鼠标控制1> mouse functions2> mouse functions demo3> mouse drag demo四: keyboard控制1> keyboard functions2> …...

flink1.18 编译遇到的问题

1. flink-runtime-web编译失败 源码编译时一直卡在 [INFO] Running ‘npm ci --cache-max0 --no-save’ in 处理方法&#xff1a; 修改flink-runtime-web/pom.xml文件 将<arguments>ci --cache-max0 --no-save ${npm.proxy}</arguments> 替换为&#xff1a;<a…...

2024年8月份编译Openwrt系统基础

概述&#xff1a; 本文档记录openwrt系统的编译过程&#xff0c;以备后续再用&#xff0c;技术支持与指导&#xff01; 1.编译环境 环境需要Linux&#xff0c;我使用的环境是WSL2、Ubuntu 20.04 2.安装编译必须的依赖&#xff08;wsl、linux&#xff09; WSL2&#xff1a;Bu…...

Vue3+vite+ts 项目使用mockjs

1、安装mockjs npm i mockjs 2、安装vite-plugin-mock npm i vite-plugin-mock -D 3、安装axios npm i axios 4.在src目录下创建mock文件夹,在文件夹内创建login.ts等文件&#xff0c;并在文件夹内放置以下内容&#xff08;注&#xff1a;URL要和真实请求地址保持一致&am…...

动态规划(二)——例题

目录 Help Jimmy 题目 解题思路 神奇的口袋 题目 枚举的解法 递归的解法 动态规划的解法 滑雪 题目 解题思路 解法一 解法二 Help Jimmy 题目 "Help Jimmy" 是在下图所示的场景上完成的游戏&#xff1a; 场景中包括多个长度和高度各不相同的平台。地面是…...

Node.js中判断是文件还是文件夹的多种方法

在Node.js中&#xff0c;我们经常需要判断一个路径是文件还是文件夹。Node.js提供了多种方法来实现这一功能&#xff0c;本文将详细介绍这些方法&#xff0c;并给出相应的示例代码。 一、使用fs.Stats对象 在Node.js中&#xff0c;fs模块提供了fs.stat()或fs.statSync()方法&…...

idea 如何打war包

idea 如何打war包 1.在IntelliJ IDEA中打包WAR文件&#xff0c;你可以按照以下步骤操作:1.设置项目结构:首先&#xff0c;打开IDEA&#xff0c;选择File>Project Structure(或使用快捷键CtrlAltShiftS)。在打开的窗口中&#xff0c;选择 Artifacts 选项 2.添加Web Applicat…...

米联客-FPGA程序设计Verilog语法入门篇连载-15 Verilog语法_跨时钟域设计

软件版本&#xff1a;无 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用所有系列FPGA 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑&#xff01; 1概述 本小节主要讲解Verilog语法的…...

gradio 对话界面实现支持图片、视频正常显示

参考: https://www.gradio.app/docs/gradio/chatbot 问题: gradio网页输出视频nan;图片webp显示不出来 解决方法:需要通过gradio的Video、Image包装 代码: 这里下面启动个后端vlm模型(参考:https://blog.csdn.net/weixin_42357472/article/details/141126225),前端通…...

催收业务怎么提高接通率

提高催收呼叫业务的接通率是一个综合性的任务&#xff0c;需要从多个方面进行优化。以下是一些具体的策略和建议&#xff1a; 一、优化呼叫时间与频次 1. 选择合适的呼叫时间&#xff1a;通过分析目标客户的活跃时段&#xff0c;选择他们最可能接听电话的时间进行呼叫…...

动态生成sitemaps和robots.txt文件:提升SEO与网站可爬性

本文由 ChatMoney团队出品 在现代Web开发中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;是网站成功的关键因素之一。搜索引擎通过网络爬虫来索引网页&#xff0c;而sitemaps和robots.txt文件则是帮助这些爬虫更好地理解和索引网站内容的重要工具。 sitemaps简介 Sit…...

LeetCode 第二十五天 2024.8.12

1. &#xff1a;递增子序列 题目链接: 491. 非递减子序列 - 力扣&#xff08;LeetCode&#xff09; 应用条件&#xff1a;回溯 难点&#xff1a; 这道题的难点在于如何去重&#xff0c;肯定不能像我们在组合中去重那样对数组排序。而且我们是要对每一层进行去重&#xff0c;…...

Elasticsearch 全文查询详解

全文查询&#xff08;Full-Text Query&#xff09;是 Elasticsearch 中的核心功能之一&#xff0c;用于对非结构化文本数据进行高效检索。与结构化查询不同&#xff0c;全文查询不仅仅是简单的精确匹配&#xff0c;还包括对文本进行分析和处理&#xff0c;从而实现更复杂的搜索…...

20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡

df -h mount fdisk无效 20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡 2024/8/10 21:19 缘起&#xff1a;当时比较便宜96.9&#xffe5;/想看看256GB的TF卡的高速卡的效果&#xff0c;就在京东入手了3张三星的高速TF卡。最近在弄RK3588S&#xff0c…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...