Parade Series - CoreAudio Loopback

Scenario

鉴于业务场景需要, 经过技术路径探索, 发现 comtypes 兼容性过于混乱,故而考虑整合一个 CoreAudio 的轮子dll来解决实际问题!

在这里插入图片描述
在这里插入图片描述
std::StringStream ⇒ std::ios::binary ⇒ std::ofstream
在这里插入图片描述
在这里插入图片描述

Loopback.dll

#ifndef _DLL_CORE_AUDIO_LOOPBACK_LOCK
#define _DLL_CORE_AUDIO_LOOPBACK_LOCK#pragma data_seg("Shared")
HANDLE hMutex = NULL;
UINT   liveIndex = 0;
CComPtr<IMMDeviceEnumerator> pEnumerator;
#pragma data_seg()
#pragma comment(linker, "/section:Shared,rws")
class TimespanGuard {
public:TimespanGuard(){this->_bof_time = GetTickCount();this->_token = "Timespan";}TimespanGuard(std::string token){this->_bof_time = GetTickCount();_token = token;}~TimespanGuard(){this->_eof_time = GetTickCount();std::cout << "" << this->_token << " > " << (this->_eof_time - this->_bof_time) << "ms elapsed" << std::endl;}private:DWORD _bof_time, _eof_time;std::string _token;
};
CORE_AUDIO_LOOPBACK_API BOOL WINAPI init(UINT devNum)
{TimespanGuard timespanGuard("init");HRESULT hr{};CoInitializeGuard coInitializeGuard;if (FAILED(coInitializeGuard.result())) {return (FALSE);    // BOOL FALSE 0x0000}hr = pEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));if (FAILED(hr)) {return (FALSE);    // BOOL FALSE 0x0000}Sleep(10);return (TRUE);         // BOOL TRUE  0x0001
}

在这里插入图片描述

CORE_AUDIO_LOOPBACK_API BOOL WINAPI getChunk(UINT devNum, UINT (*dtChunk)[2], UINT nDimension)
{TimespanGuard timespanGuard("getChunk");HRESULT hr{};CoInitializeGuard coInitializeGuard;if (FAILED(coInitializeGuard.result())) {return (FALSE);    // BOOL FALSE 0x0000}hr = pEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));if (FAILED(hr)) {return (FALSE);    // BOOL FALSE 0x0000}std::cout << "getChunk > " << (nDimension) << "x" << (2) << std::endl;for (int i = 0; i < nDimension; i++) {printf("\t#%.4d ", i);for (int j = 0; j < 2; j++) {printf("%8d ", dtChunk[i][j]);dtChunk[i][j] = dtChunk[i][j] + 100;}printf("\n");}Sleep(10);return (TRUE);         // BOOL TRUE  0x0001
}
CORE_AUDIO_LOOPBACK_API BOOL WINAPI release(UINT devNum)
{TimespanGuard timespanGuard("release");CoUninitialize();return (TRUE);         // BOOL TRUE  0x0001
}

XAudio.py

import ctypesif True:loopback = ctypes.CDLL("loopback.dll")if True:loopback.getAudio.argtypes = [c_int, c_char_p, c_int]loopback.getAudio.restype = c_intdevNum = c_int(0)bytesSize = 256bytesName = (' ' * bytesSize).encode('utf-8')result = loopback.getAudio(devNum, bytesName, bytesSize)print('DLL invoked > ', result, (bytesName.decode('gb2312')))

GetBitmapBits 后位图颠倒

	dumpCache(dataBuff, result);GetBitmapBits(hOutputBitmap, nBytesSize, rawData); // 获取位图的位for (int i = 0; i < nBytesSize; i++) {int row, column = 0;row = (sHeight - (i / bm.bmWidthBytes)) - 1;column = (i % bm.bmWidthBytes);dataBuff[result + row * bm.bmWidthBytes + column] = (rawData[i] & 0x00FF);}result += nBytesSize;
dumpCache(dataBuff, result);

dumpCache

BOOL dumpCache(BYTE* dataBuff, UINT buffSize)
{for (int i = 0; i < buffSize; i++) {printf("%.2X ", dataBuff[i]);if (i % 16 == 15)printf("\n");}printf("\n");return (TRUE);
}

getBitmapHeader

UINT getBitmapHeader(HDC hDC, HBITMAP hBitmap, BYTE* dataBuff, UINT buffSize)
{UINT result = 0;int iBits;//当前显示分辨率下每个像素所占字节数WORD wBitCount;//位图中每个像素所占字节数//定义调色板大小, 位图中像素字节大小 , 位图文件大小 , 写入文件字节数DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;BITMAP Bitmap;//位图属性结构BITMAPFILEHEADER bmfHdr;//位图文件头结构BITMAPINFOHEADER bi;//位图信息头结构LPBITMAPINFOHEADER lpbi;//指向位图信息头结构HANDLE fh, hDib, hPal;HPALETTE hOldPal = NULL;//定义文件,分配内存句柄,调色板句柄//计算位图文件每个像素所占字节数iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);if (iBits <= 1)wBitCount = 1;else if (iBits <= 4)wBitCount = 4;else if (iBits <= 8)wBitCount = 8;else if (iBits <= 24)wBitCount = 24;elsewBitCount = 32;//计算调色板大小if (wBitCount <= 8)dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);//设置位图信息头结构GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);bi.biSize = sizeof(BITMAPINFOHEADER);bi.biWidth = Bitmap.bmWidth;bi.biHeight = Bitmap.bmHeight;bi.biPlanes = 1;bi.biBitCount = wBitCount;bi.biCompression = BI_RGB;bi.biSizeImage = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrUsed = 0;bi.biClrImportant = 0;dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;//为位图内容分配内存hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);*lpbi = bi;// 处理调色板  hPal = GetStockObject(DEFAULT_PALETTE);if (hPal){hDC = ::GetDC(NULL);hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);RealizePalette(hDC);}// 获取该调色板下新的像素值GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize, (BITMAPINFO*)lpbi, DIB_RGB_COLORS);//恢复调色板  if (hOldPal){SelectPalette(hDC, hOldPal, TRUE);RealizePalette(hDC);::ReleaseDC(NULL, hDC);}// 设置位图文件头bmfHdr.bfType = 0x4D42; // "BM"dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;bmfHdr.bfSize = dwDIBSize;bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;// 写入位图文件头memcpy(dataBuff, (BYTE*)&bmfHdr, sizeof(BITMAPFILEHEADER));result += sizeof(BITMAPFILEHEADER);memcpy((dataBuff + result), (BYTE*)lpbi, ((DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize));result += sizeof(BITMAPINFOHEADER);result += dwPaletteSize;//清除  GlobalUnlock(hDib);GlobalFree(hDib);return (result);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/636149.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git - 在PyCharm/Idea中集成使用Git

文章目录 Git - 在PyCharm/Idea中集成使用Git1.新建GitHub仓库2.将仓库与项目绑定3.在PyCharm中使用Git4.新建Gitee仓库5.将仓库与项目绑定6.在IDEA中使用Git Git - 在PyCharm/Idea中集成使用Git 本文详细讲解了如何在 PyCharm 或 Idea 中配置 Gitee 或 GitHub 仓库&#xff0…

*Linux系统的进程和计划任务管理

目录 一、查看进程 1、程序和进程的关系 *2、ps查看静态进程信息 1&#xff09;ps aux 2&#xff09;ps -elf *3、top查看动态进程信息 4、pgrep查看进程信息 5、pstree查看进程树 二、控制进程 1、进程启动方式 2、进程的前后台调度 3、终止进程的运行 三、计划任…

HCF-Net:用于红外小目标检测的分层上下文融合网络

摘要 红外小目标检测是一项重要的计算机视觉任务&#xff0c;涉及在红外图像中识别和定位微小物体&#xff0c;这些物体通常仅包含几个像素。然而&#xff0c;由于物体尺寸极小以及红外图像中通常复杂的背景&#xff0c;这项任务面临困难。在本文中&#xff0c;我们提出了一种…

【Unity学习笔记】第十三 · tag与layer(运行时创建tag和layer)

参考&#xff1a; Unity手册 标签Unity手册 LayersIs it possible to create a tag programmatically?脚本自动添加tag和Layer 注&#xff1a;本文使用Unity版本是2022.3.23f1 转载引用请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/de…

政安晨:【深度学习神经网络基础】(十二)—— 深度学习概要

目录 概述 深度学习的概况 深度学习的组成部分 部分标记的数据 修正线性单元 卷积神经网络 神经元Dropout GPU训练 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨益&#xf…

NVIDIA安装程序失败-Nsight Visual Studio Edition失败解决办法

博主是要升级cuda版本&#xff0c;那么在安装新版本之前需要卸载以前的版本。 博主一溜卸载下去&#xff0c;最后有这么个东西卸载不掉&#xff0c;Nsight Visual Studio Edition 不管是电脑系统卸载还是360卸载&#xff0c;都卸载不掉。 此时安装新的cuda也遇到了这个问题 由…

项目7-音乐播放器5+注册账号

前端之登录注册页面案例_前端登录页面-CSDN博客 1.前端代码 MAPPER Insert("insert into user(username,password) values (#{username},#{password}) ")Integer insertUserInfo(String username,String password); Service public Result insertUserInfo(String…

抓取内网windows密码和利用hash横向及相关问题

目录 实验准备 用msf拿到shell 抓取hash和明文密码 相关问题 问题1.通过hashdump抓取所有用户的密文为什么分成两个模块&#xff0c;这两个模块分别代表什么 &#xff1f; 问题2.为什么第一个模块 永远是一样的aad3&#xff1f; 问题3.这两个模块的加密算法有什么不同&a…

多因子模型的因子分组-克隆巴赫α系数

优质博文&#xff1a;IT-BLOG-CN 在建立我们的Alpha模型之前&#xff0c;我们得先知道什么是Alpha&#xff1f;Alpha是一条或者一系列能够预测股票走势的信息资讯组合。而这每一条非随机的信息资讯&#xff0c;我们称之为多因子模型的因子。多因子模型因子的选择需要避免系统性…

树莓派3B长时间不操作屏幕息屏无信号处理

树莓派外接显示器&#xff0c;需长时间展示某个网页&#xff0c;经过一段时间&#xff0c;显示器屏幕会黑掉显示无信号。 需修改 /etc/lightdm/lightdm.conf 配置文件中新增如下两行并重启。 xserver-commandX -s 0 dpms sleep-inactive-timeout0

CCF-CSP真题《202312-2 因子化简》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202312-2试题名称&#xff1a;因子化简时间限制&#xff1a;2.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 题目背景 质数&#xff08;又称“素数”&#xff09;是指…

【Arduino IDE 环境配置】

目录 Arduino IDE 环境配置 1. 安装方式2. 操作方法&#xff08;Arduino中文社区&#xff09; 2.1. 安装Arduino IDE2.2. 下载固件2.3. 修改Arduino IDE语言2.4. 添加开发板管理网址2.5. 运行离线包2.6. 检查安装是否成功 下载Arduino IDE&#xff1a; 如果你还没有安装Arduin…