桌面录音

Windows下如何对声卡音频输出进行录音 对系统播放出来的声音进行录音是一个比较常见的需求,比如各类直播工具,就会把主播的声音经过麦克风采集下来,再与电脑里播放的音乐合成(也就是混音),再推送到CDN,分发给观众。 微软提供的Core Audio APIs中的WASAPI即是用来实现这一功能的。 先看这个https://docs.microsoft.com/zh-cn/windows/win32/coreaudio/core-audi... 阅读详情

  公司做一个项目,需要把 windows 扬声器的声音捕捉下来,这个可以参考MSDN文档,上面有示例程序:
Loopback Recording

Capturing a Stream

这程序并不完整,还需要做一些修改才行:

下面是我 调试通过的代码:

#include <Mmdeviceapi.h>
#include <Audioclient.h>

//-----------------------------------------------------------
// Record an audio stream from the default audio capture
// device. The RecordAudioStream function allocates a shared
// buffer big enough to hold one second of PCM audio data.
// The function uses this buffer to stream data from the
// capture device. The main loop runs every 1/2 second.
//-----------------------------------------------------------

// REFERENCE_TIME time units per second and per millisecond
#define REFTIMES_PER_SEC  10000000
#define REFTIMES_PER_MILLISEC  10000

#define EXIT_ON_ERROR(hres)  \
    if (FAILED(hres)) { goto Exit; }

#define SAFE_RELEASE(punk)  \
    if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }


const CLSID CLSID_MMDeviceEnumerator    = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator       = __uuidof(IMMDeviceEnumerator);
const IID IID_IAudioClient              = __uuidof(IAudioClient);
const IID IID_IAudioCaptureClient       = __uuidof(IAudioCaptureClient);



class MyAudioSink {
public:
        //WAVEFORMATEX *pwfx = NULL;
        int     SetFormat(WAVEFORMATEX *pwfx);

        int     CopyData(char * pData,UINT32 numFramesAvailable,BOOL *pbDone);
};



int MyAudioSink::SetFormat(WAVEFORMATEX *pwfx)
{
    printf("wFormatTag is %x\n",        pwfx->wFormatTag);
    printf("nChannels is %x\n",         pwfx->nChannels);
    printf("nSamplesPerSec is %d\n",    pwfx->nSamplesPerSec);
    printf("nAvgBytesPerSec is %d\n",   pwfx->nAvgBytesPerSec);
    printf("wBitsPerSample is %d\n",    pwfx->wBitsPerSample);

    return 0;
}

int MyAudioSink::CopyData(char *    pData,UINT32 numFramesAvailable,BOOL *pbDone)
{
    if(pData != NULL)
        fwrite(pData, numFramesAvailable ,1,fp);

    return 0;
}

/// pwfx->nSamplesPerSec    = 44100; 
/// 不支持修改采样率, 看来只能等得到数据之后再 swr 转换了 
BOOL AdjustFormatTo16Bits(WAVEFORMATEX *pwfx)
{
    BOOL bRet(FALSE);

    if(pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
    {
        pwfx->wFormatTag = WAVE_FORMAT_PCM;
        pwfx->wBitsPerSample = 16;
        pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
        pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;

        bRet = TRUE;
    }
    else if(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
    {
        PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);
        if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat))
        {
           pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
           pEx->Samples.wValidBitsPerSample = 16;
           pwfx->wBitsPerSample = 16;
           pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
           pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;

           bRet = TRUE;
        } 
    }

    return bRet;
}

HRESULT RecordAudioStream(MyAudioSink *pMySink)
{
    HRESULT             hr;
    REFERENCE_TIME      hnsActualDuration;
    UINT32              bufferFrameCount;
    UINT32              numFramesAvailable;
    BYTE *              pData;
    DWORD               flags;
    REFERENCE_TIME      hnsDefaultDevicePeriod(0);

    REFERENCE_TIME          hnsRequestedDuration    = REFTIMES_PER_SEC;
    IMMDeviceEnumerator*    pEnumerator             = NULL;
    IMMDevice *             pDevice                 = NULL;
    IAudioClient *          pAudioClient            = NULL;
    IAudioCaptureClient *   pCaptureClient          = NULL;
    WAVEFORMATEX *          pwfx                    = NULL;
    UINT32                  packetLength            = 0;
    BOOL                    bDone                   = FALSE;
    HANDLE                  hTimerWakeUp            = NULL; 

    hr = CoCreateInstance( CLSID_MMDeviceEnumerator, NULL,CLSCTX_ALL, IID_IMMDeviceEnumerator,(void**)&pEnumerator );

    EXIT_ON_ERROR(hr)

    hr = pEnumerator->GetDefaultAudioEndpoint( eRender /*eCapture*/, eConsole, &pDevice );

    EXIT_ON_ERROR(hr)

    hr = pDevice->Activate( IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);
    EXIT_ON_ERROR(hr)

    hr = pAudioClient->GetDevicePeriod(&hnsDefaultDevicePeriod, NULL);

    hr = pAudioClient->GetMixFormat(&pwfx);
    EXIT_ON_ERROR(hr)

    AdjustFormatTo16Bits(pwfx);

    hTimerWakeUp = CreateWaitableTimer(NULL, FALSE, NULL);


    hr = pAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,AUDCLNT_STREAMFLAGS_LOOPBACK /*0*/ ,0 ,0,pwfx,NULL );

    EXIT_ON_ERROR(hr)

    // Get the size of the allocated buffer.
    hr = pAudioClient->GetBufferSize(&bufferFrameCount);
    EXIT_ON_ERROR(hr)

    hr = pAudioClient->GetService( IID_IAudioCaptureClient, (void**)&pCaptureClient);
    EXIT_ON_ERROR(hr)

    LARGE_INTEGER liFirstFire;
    liFirstFire.QuadPart = -hnsDefaultDevicePeriod / 2; // negative means relative time
    LONG lTimeBetweenFires = (LONG)hnsDefaultDevicePeriod / 2 / (10 * 1000); // convert to milliseconds

    BOOL bOK = SetWaitableTimer(hTimerWakeUp,&liFirstFire,lTimeBetweenFires,NULL, NULL, FALSE);

    // Notify the audio sink which format to use.
    hr = pMySink->SetFormat(pwfx);
    EXIT_ON_ERROR(hr)

    // Calculate the actual duration of the allocated buffer.
    hnsActualDuration = (double)REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;

    /*************************************************************/
    hr = pAudioClient->Start();  // Start recording.
    EXIT_ON_ERROR(hr)
    HANDLE waitArray[1] = { /*htemp hEventStop,*/ hTimerWakeUp };

    // Each loop fills about half of the shared buffer.
    while (bDone == FALSE)
    {
        // Sleep for half the buffer duration.
        //Sleep(hnsActualDuration/REFTIMES_PER_MILLISEC/2);
        //WaitForSingleObject(hTimerWakeUp,INFINITE);
        WaitForMultipleObjects(sizeof(waitArray)/sizeof(waitArray[0]), waitArray, FALSE, INFINITE);
        //WaitForMultipleObjects(sizeof(waitArray)/sizeof(waitArray[0]), waitArray, FALSE, INFINITE);

        hr = pCaptureClient->GetNextPacketSize(&packetLength);
        EXIT_ON_ERROR(hr)

        while (packetLength != 0)
        {
            // Get the available data in the shared buffer.
            hr = pCaptureClient->GetBuffer( &pData, &numFramesAvailable,&flags, NULL, NULL);
            EXIT_ON_ERROR(hr)

            //if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
            //{
            //  pData = NULL;  // Tell CopyData to write silence.
            //}

            // Copy the available capture data to the audio sink.
            hr = pMySink->CopyData((char *) pData, numFramesAvailable * pwfx->nBlockAlign, &bDone);
            EXIT_ON_ERROR(hr)

            hr = pCaptureClient->ReleaseBuffer(numFramesAvailable);
            EXIT_ON_ERROR(hr)

            hr = pCaptureClient->GetNextPacketSize(&packetLength);
            EXIT_ON_ERROR(hr)
        }
    }

    hr = pAudioClient->Stop();  // Stop recording.
    EXIT_ON_ERROR(hr)

Exit:
    CoTaskMemFree(pwfx);
    SAFE_RELEASE(pEnumerator)
    SAFE_RELEASE(pDevice)
    SAFE_RELEASE(pAudioClient)
    SAFE_RELEASE(pCaptureClient)

    return hr;
}


int _tmain(int argc, _TCHAR* argv[])
{
    fp      = fopen("F://work//record.pcm","wb");
    CoInitialize(NULL);
    MyAudioSink test;

    RecordAudioStream(&test);

    return 0;
}

留着以后使用

javafx实现桌面录屏录音软件 在javafx中,实现了一个桌面录屏,录音软件,实现对桌面图像的实施捕获,麦克风声音的录制,然后整合成一个mp4格式的视频文件,可在视频播放器中播放录制的音视频。 阅读详情

相关推荐

C#(ffmpeg) 高清桌面录制+本地录音+麦克风录音

C#(ffmpeg) 高清桌面录制+本地录音+麦克风录音

dsruanjian的博客 413

Windows捕获系统声音

最近在写键盘配套的上位机,在写音乐律动灯效时需要实时捕获系统声音,在windows上需要使用 到CoreAudio的Loopback模式捕获。代码在Qt平台上运行,编译环境Qt5.15.2 MSVC2019 64bit以及Qt6.4.3 MSVC2019 64bit。信号发出后,在MainWindow的槽函数进行数据重排列、fft处理,就可以的到频谱了。这里用的fft库是kissfft,可在github上下载。

ok6018234的博客 1579

【神狐录音机V2.0】简单好用的电脑桌面录音软件

神狐录音机是一款专为Windows用户设计的高品质录音工具,支持无损音质录制,操作简单易上手。它可捕捉电脑播放器音频或麦克风输入,一键启动录制,并支持自定义快捷键和后台静默录制。功能上提供不限时长录制、无损音质输出、文件智能压缩,以及定时录制和多格式导出(MP3/WAV等),满足日常办公、学习及专业场景需求。其开源特性更增添了可靠性,是高效实用的录音解决方案。

dwj137的博客 280

智能客服客户端程序开发

这个国庆节作死,答应别人在七天内做2个项目。智能客服项目是其中一个,当时是答应给隔壁兄弟团队做的。他们说实在搞不定了,节后要上线,我就因为随口说了一句:“这有什么难的”,结果祸从口出,这事情就落我头上了。 录音识别是智能客服大项目计划里面的一部分,简单说就是客户在跟用户聊天的时候,实时从声卡上抓取音频数据,然后发送给阿里云-智能语音交互识别成句子文本后,再发送给我们的智能客服助手服务器,生成提示...

icenic的专栏 958

桌面录音软件,WEBEX工具

桌面录音软件,WEBEX工具,可实现记录语音和桌面操作

一款可以轻松录音的软件

一款可以轻松录音的软件,让你在无聊的时候轻轻松松的放松一下自己。

WASAPI 01 采集默认设备的音频

音频采集或播放时,需要用MMDevice API来枚举和获取指定设备,用WASAPI来处理应用程序和音频设备之间的音频流数据,如采集或播放。1. MMDevice APIThe Windows Multimedia Device (MMDevice) API enables audio clients to discover audio endpoint devices, determine th...

建建的博客 6416

扬声器 声卡 录音 保存wav文件

语言:C++ 环境:VS2013 参考开源项目:OBS 功能介绍:捕获声卡的音频数据 保存为wav文件

在远程桌面会话主机上配置录音重定向

远程桌面连接windows 7 或 windows server 2008 R2 时,无法对远程计算机进行录音的解决方法,就是启动录音重定向(Allow recording redirection)。 微软网站KB的解决方法:http://support.microsoft.com/kb/2020918 录音重定向可让用户在远程会话中对远程计算机进行录音。用户可以通过在“...

weixin_34392435的博客 2219

别再死记硬背了!用LTspice和Simulink仿真,5分钟搞懂巴特沃斯、切比雪夫、贝塞尔滤波器的区别

本文通过LTspice和Simulink仿真工具,直观对比了巴特沃斯、切比雪夫和贝塞尔滤波器的特性差异。从通带波纹、过渡带陡峭度到相位线性度,详细解析了三种经典滤波器的设计哲学与应用场景,帮助工程师和学生快速掌握滤波器选型技巧,提升电路设计效率。

weixin_33910191的博客 523

1.2 固态变压器:传统工频变压器的局限与SST的技术起源

本小节明确传统工频变压器在电力系统中的基础定位与核心工作特性,系统分析其在新型电力系统场景下的固有技术瓶颈,梳理固态变压器(Solid State Transformer, SST,又称电力电子变压器Power Electronic Transformer, PET)从概念提出到工程化成熟的完整演进路径,为后续SST技术优势、设计需求与规范符合性要求的讲解建立底层逻辑,同时对应GB/T 40429-2021《电力电子变压器通用技术要求》的需求制定背景。

技术工作者 657

win7计算机怎么放在桌面上,Win7系统怎么在电脑上录音并放在桌面上图文教程

最近有部分用户反映需要用自己的电脑完成录音,并且把它保存到桌面上,如果要下载软件又怕麻烦,现在小编就以win7系统为例,讲解如何在电脑上录音并放在桌面上,需要的用户快来看看吧。步骤如下:首先打开开始菜单,在开始菜单最下方有一个搜索框,你可以在这里面搜索系统的功能及开始菜单中的程序快捷方式。在 搜索框中输入录音二字,如图所示,你也可以通过点击所有程序,然后在附件中查找到这个系统自带的录音程序。此时在...

weixin_35720618的博客 680

5G核心技术:N3与N4接口深度解析

5G网络中,N3和N4接口是实现用户数据传输的核心。N3接口是gNB与UPF之间的用户面通道,采用GTP-U协议封装数据,通过UDP/IP传输,确保低时延和业务隔离。N4接口是SMF与UPF之间的控制面链路,基于PFCP协议下发转发规则(FAR/TDR/QER/URR),实现精细化流量控制。二者协同工作:N4下发策略(如QoS、计费规则),N3执行数据转发,共同支持5G三大场景(eMBB/uRLLC/mMTC),体现控制与转发分离(CUPS)架构优势。

Qinti_mm的博客 1633

win7计算机怎么放在桌面上,Win7电脑怎么录音并放在桌面上?

我们天天都有用到电脑,有时候因某种原因需要录音,然后去网上下软件又有点麻烦。这时候我们就可以打开Windows系统中自带的一个录音功能,我们可以用这个简单的录音程序来录制声音,并且把所录制的声音保存到电脑上。那要如何打开这个功能在电脑上录音呢?现在就由小编和大家介绍一下Win7电脑怎么录音并放在桌面上的方法。步骤如下:1、首先打开开始菜单,在开始菜单最下方有一个搜索框,你可以在这里面搜索系统的功能...

weixin_39606003的博客 357

ROS 2实战:用MoveIt Task Constructor让机械臂完成抓取任务(附避坑指南)

本文详细介绍了如何在ROS 2环境中使用MoveIt Task Constructor框架,为Franka Panda机械臂构建一个完整的拾取放置任务流水线。通过分解任务阶段、配置规划器并处理实际部署中的常见问题,帮助开发者从基础运动规划升级到可靠的多步骤任务编排,并附有核心避坑指南。

vvv99的博客 505

告别谷歌翻译失效!手把手教你用Immersive Translate插件实现双语网页阅读(附Chrome/Edge/Firefox保姆级配置)

本文详细介绍了如何使用Immersive Translate插件实现双语网页阅读,解决谷歌翻译失效的问题。通过Chrome、Edge和Firefox的保姆级配置指南,帮助用户轻松安装和使用这款支持双语对照、智能识别网页内容的翻译插件,提升外文资料阅读效率。

weixin_28683689的博客 485

终极指南:如何在Electron中实现桌面端录音功能

想要在Electron桌面应用中添加录音功能吗?Recorder库为你提供了完整的解决方案!作为一款强大的HTML5录音库,Recorder不仅支持浏览器环境,还能完美集成到Electron应用中,让你轻松实现桌面端的音频录制和处理。 ## 📍 为什么选择Recorder进行Electron录音开发? Recorder是一个专业的HTML5录音库,支持MP3、WAV、OGG、WebM、AMR

gitblog_01098的博客 567

VisionPro 机器视觉案例 之 硬币识别

CogPMAlignTool模板匹配工具 掩模

机器视觉李小白的博客 1892

从 ScriptProcessor 到 AudioWorklet:Electron 桌面端录音实践总结

本文总结了在Electron桌面应用中实现录音功能的实践过程。最初使用ScriptProcessorNode导致系统蓝屏,改用AnalyserNode又出现音频噪声问题,最终采用AudioWorkletNode成功实现了稳定、低延迟的音频采集。文章详细对比了三种方案的优缺点,重点介绍了AudioWorklet的实现方法,包括获取麦克风流、创建音频上下文、处理PCM数据等关键步骤,并针对Electron环境提供了特殊处理建议。最终方案支持16kHz采样率的Int16格式PCM数据流式传输,完美适配后端ASR处

多看书少吃饭的博客 1348

【施磊】C++课程笔记目录

【C++编程】施磊老师C++笔记目录

GeniusAng的博客 4122

ZED双目相机环境配置

ZED SDK 安装文件夹中有一个 Python 脚本(get_python_api.py),可以自动检测操作系统、CUDA 和 Python 版本并下载相应的预编译 Python API 包(pyzed)。安装SDK成功后,我们进入ZED SDK文件夹中的tools子文件夹,运行ZED Explorer.exe 以及 ZED Depth Viewer.exe,查看ZED相机是否能正常启用工作。在本例中,我们简单地检索ZED相机的序列号:打开 ZED相机,然后打印其序列号,然后关闭相机。

qq_53545309的博客 2134

macOS下OBS没有桌面声音且不录音

目前使用的macOS Catalina 10.15.5,由于新版系统权限问题,OBS无法自动取得桌面声音,只能依靠第三方软件soundflower。 soundflower可以从官方网站下载。 安装好soundflower之后,就可以在OBS设置里启用桌面声音64ch。如下图所示: 另外在系统偏好设置 声音里也要设置为64ch,并且让在菜单栏中显示设置,方便修改。如下图所示: 这样设置之后,OBS的桌面声音就可以录音了。 ...

小龙在线 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Qt跨平台开发:Qwen3-TTS桌面录音棚软件

本文介绍了如何在星图GPU平台自动化部署【声音克隆】Qwen3-TTS-12Hz-1.7B-Base镜像,实现高效的语音克隆与合成功能。该镜像可应用于有声读物制作,通过录制参考音频快速生成特定角色的语音,大幅提升音频内容创作效率和质量。

weixin_36474001的博客 280

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

融合调度平台录音模块设计与行业落地|桌面调度系统录音功能解析

本文从技术与落地视角解析桌面调度系统录音模块,介绍多条件检索、在线回放、通话存证、RBAC 权限管控的设计思路,对比传统独立录音方案差异,分享融合调度录音在工业项目落地要点。

专注于HWT 2.0应急调度系统与融合通讯技术,为政府、医疗、化工、石油、煤矿、交通、公安、消防等众多领域提供智能通讯解决方案,融合通讯、智能客服、AI语音智能技术,打造一站式融合通讯服务平台。 142

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

声云录音卡完整入门:一张BLE录音卡片如何打通Android、iOS、鸿蒙与桌面全平台

声云录音卡 Recorder 是一套面向开发者和行业客户的智能录音硬件接入方案:它以录音卡片硬件为核心,开放 **BLE 协议 SDK** 和 Android、iOS、鸿蒙(HarmonyOS)、Flutter 接入示例,同时提供 Windows/macOS 桌面端 Demo。读完本篇指南,你将知道如何从“扫描连接”一路走到“录音、文件传输、语音转写”,最快 5 分钟跑通全平台链路。 ## 认识

gitblog_00696的博客 109
上一篇: 一个由于锁的作用域导致core dump的问题的解决
下一篇: pcm音量计算
xianjian_x
博客等级 码龄14年 231粉丝 43原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值