1. 程式人生 > >windows下簡單的音訊採集示例

windows下簡單的音訊採集示例

最近需要在window下進行音訊採集,網上找了很久都沒找到win7下如何採集pcm資料的完整示例,經過一翻折騰後寫了一個很簡單的demo程式以供同行進行參考,如有不正確的地方請指正

本例是採用audio core進行音訊採集

程式碼塊

#include "stdafx.h"
#include <MMDeviceAPI.h>
#include <AudioClient.h>
#include <AudioPolicy.h>

#define MAX_AUDIO_FRAME_SIZE 192000

template <class T> void SafeRelease(T **ppT)
{
if (*ppT)
{
    (*ppT)->Release();
    *ppT = NULL;
}
}

int _tmain(int argc, _TCHAR* argv[])
{

    IAudioClient *      _AudioClient;
    IAudioCaptureClient *_CaptureClient;
    IMMDevice * _Device;
    IMMDeviceEnumerator *deviceEnumerator = NULL;
    HANDLE _AudioSamplesReadyEvent=NULL;

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&deviceEnumerator));
    if (FAILED(hr))
    {
        printf("Unable to retrieve CoCreateInstance %x\n", hr);
        goto Exit;
    }
    //這裡可以呼叫EnumAudioEndpoints選擇使用其它裝置
    hr = deviceEnumerator->GetDefaultAudioEndpoint(eCapture,eMultimedia,&_Device);
    if (FAILED(hr))
    {
        printf("Unable to retrieve device %x\n", hr);
        goto Exit;
    }
    SafeRelease(&deviceEnumerator);

    _Device->AddRef();    // Since we're holding a copy of the endpoint, take a reference to it.  It'll be released in Shutdown();

    _AudioSamplesReadyEvent = CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
    if (_AudioSamplesReadyEvent == NULL)
    {
        printf("Unable to create samples ready event: %d.\n", GetLastError());
        return false;
    }

    hr = _Device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, reinterpret_cast<void **>(&_AudioClient));
    if (FAILED(hr))
    {
        printf("Unable to activate audio client: %x.\n", hr);
        return false;
    }

    WAVEFORMATEX *      _MixFormat;
    UINT32              _BufferSize;
    hr = _AudioClient->GetMixFormat(&_MixFormat);
    if (FAILED(hr))
    {
        printf("Unable to get mix format on audio client: %x.\n", hr);
        return false;
    }

    size_t _FrameSize = (_MixFormat->wBitsPerSample / 8) * _MixFormat->nChannels;

    //InitializeAudioEngine
    hr = _AudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, 20*10000, 0, _MixFormat, NULL);

    if (FAILED(hr))
    {
        printf("Unable to initialize audio client: %x.\n", hr);
        return false;
    }

    //
    //  Retrieve the buffer size for the audio client.
    //
    hr = _AudioClient->GetBufferSize(&_BufferSize);
    if(FAILED(hr))
    {
        printf("Unable to get audio client buffer: %x. \n", hr);
        return false;
    }
    hr = _AudioClient->SetEventHandle(_AudioSamplesReadyEvent);
    if (FAILED(hr))
    {
        printf("Unable to set ready event: %x.\n", hr);
        return false;
    }

    hr = _AudioClient->GetService(IID_PPV_ARGS(&_CaptureClient));
    if (FAILED(hr))
    {
        printf("Unable to get new capture client: %x.\n", hr);
        return false;
    }

    //開始採集

    hr = _AudioClient->Start();
    if (FAILED(hr))
    {
        printf("Unable to get new capture client: %x.\n", hr);
        return false;
    }

    bool stillPlaying = true;
    while (stillPlaying)
    {
        DWORD waitResult = WaitForSingleObject( _AudioSamplesReadyEvent, INFINITE);

        BYTE *pData,*pBuffer;
        INT nBufferLenght;
        UINT32 framesAvailable;
        DWORD  flags;
        pBuffer=new BYTE[MAX_AUDIO_FRAME_SIZE];
        hr = _CaptureClient->GetBuffer(&pData, &framesAvailable, &flags, NULL, NULL);
        if (SUCCEEDED(hr))
        {
            if (framesAvailable!=0)
            {
                if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
                {
                    //
                    //  Fill 0s from the capture buffer to the output buffer.
                    //
                }
                else
                {
                    //
                    //  Copy data from the audio engine buffer to the output buffer.
                    //

                    CopyMemory(pBuffer,pData,framesAvailable*_FrameSize);
                    printf("get capture frames: %d!\n", framesAvailable);
                }
            }
            delete[] pBuffer;
            hr = _CaptureClient->ReleaseBuffer(framesAvailable);
            if (FAILED(hr))
            {
                printf("Unable to release capture buffer: %x!\n", hr);
            }
        }
    }
Exit:

    return 0;
}

特別提醒一下,我在win7下采集到的pcm資料格式是32位浮點型,如果你需要編碼成其它格式的話注意做相應的轉換

相關推薦

windows簡單音訊採集示例

最近需要在window下進行音訊採集,網上找了很久都沒找到win7下如何採集pcm資料的完整示例,經過一翻折騰後寫了一個很簡單的demo程式以供同行進行參考,如有不正確的地方請指正 本例是採用audio core進行音訊採集 程式碼塊 #include "

windowskafka配置入門 示例

keep bsp col fine program summer actor 回車 打開 實驗平臺與軟件: 操作系統:windows7 32 位 java 開發包: jdk1.8.0_144 集群: zookeeper-3.3.6 消息隊列: kafka_2.11

windows簡單配置Tensorflow

裏的 net cti span pre art color 下載速度 conda 配置tensorflow之前先要裝好Anaconda Anaconda下載地址:https://www.anaconda.com/download/ 在Windows上面裝Tensorflow

windows簡單的緩沖區溢出之slmail

經典 問題 shell ever 圖片 ttl 0x0d orm 設置斷點 緩沖區溢出是什麽? 當緩沖區邊界限制不嚴格時,由於變量傳入畸形數據或程序運行錯誤,導致緩沖區被“撐暴”,從而覆蓋了相鄰內存區域的數據 成功修改內存數據,可造成進程劫持,執行惡意代碼,獲取服務器控制權

Centos,Windows 簡單查看自己VPS使用的虛擬化技術是什麽

運行 了吧 root 使用 sys dom xen vps 自己 安裝epel和remi不用說了吧? yum install virt-what -y 運行 virt-what 我的兩臺VPS [root@tntsec ~]# virt-what xen xen-domU

Windows簡單使用BPG影象壓縮工具進行影象壓縮和解壓縮(附官方編解碼工具程式碼下載地址)

BPG是一種新型的圖片格式。其設計初衷在於當圖片質量或檔案size成為瓶頸時,取代JPEG。其主要特點如下: 高壓縮比。BPG在quality類似的情形下,比JPEG要小得多。相同大小的圖片,使用BMP儲存質量遠高於JPEG 瀏覽器支援:使用一個很小js解碼庫(54KB)

mxnet CPU版本Windows簡單安裝(python介面安裝)

話說這幾天一直想做個驗證碼識別的demo,想到一些比較時髦的方法來實現,所以選中mxnet框架來實現,安裝了幾天不成功,網上找各種教程什麼的都要安裝c++一大坨的東西,我只想安裝個cpu版本啊;下午特

Python+Opencv+Qt4編寫Windows攝像頭影象採集顯示程式

# -*- coding: utf-8 -*- # Form implementation generated from reading ui file '1.ui' # # Created: Tue Nov 14 09:45:29 2017 #      by: Py

windows執行mask-rcnn示例程式踩過的坑

環境:win10,keras2.1.6,python3.6,ensorflow1.8-gpu 錯誤一:       執行D:\python\jupyter\Mask_RCNN-master\samples目錄下的demo.ipynb檔案,用jupyter notebo

windows簡單的C語言伺服器(TCP)

回顧下windows下網路方面的東西 首先寫了下C語言的socket  --檢視本機IP:ipconfig/all ---C語言實現 ---visual studio 2012 Server: #include <stdio.h> #include <

Windows上的音訊採集技術

前一段時間接到一個任務,需要採集到音效卡的輸出訊號,以便與麥克風的輸入訊號進行混音。 之前一直沒有研究過音訊的相關技術,這次就順便抽出一點時間去了解了一下Windows上採集音訊的相關技術。 對於音訊處理的技術,主要有如下幾種: 採集麥克風輸入 採集音效卡輸出 將音訊資料送入音效卡進行播放 對多路音

Windows簡單快速搭建Flask開發環境

下載Python3 安裝virtualenv 執行命令:pip intall virtualenv 直接安裝 執行建立虛擬環境命令:virtualenv venv ,在當前目錄下會成功生產一個venv資料夾。 開啟虛擬環境:先cd venv,進入

Windowswave API 音訊採集

目的:Windows下wave API採集PCM 環境: 系統:Win10 環境:VS2015 64bit 操作步驟: 1. 匯入系統wave標頭檔案及庫 #include <mmsystem.h> #pragma com

nginx在windows多域名簡單配置

瀏覽器 local list brush 多域名 cat ges out 目錄 1. windows下安裝nginx的目錄結構如下: 2. 在nginx-1.12.1目錄下conf/nginx.conf 內容 #user nobody; worker_pro

WindowsNginx與tomcat組合簡單使用

org 轉載 服務 ima 重啟 3.2 ati 如果 點擊 本文轉載自: http://www.cnblogs.com/naaoveGIS/ 1.背景 項目中瓦片資源越來越多,如果提高瓦片的訪問效率是一個需要解決的問題。這裏,我們考慮使用Nginx來代理靜態資源進行初步解

windows使用RedisCluster集群簡單實例

綠色 nod only vid 準備 信息 sources slots 生成 一、開發環境 ruby環境準備 下載 64位的 RubyInstaller並安裝 地址http://rubyinstaller.org/downloads/勾選下面三個不用配置環境變量 Im

WindowsAnaconda的安裝和簡單使用

文獻 計算 complete detail 安裝python 就是 會有 ide over 轉載自: http://blog.csdn.net/dq_dm/article/details/47065323 Anaconda is a completely free

JAVA 基礎開發環境 vscode 搭建 WindowsVSCode編譯運行簡單java

ast devel article not warning 環境 type cal gate JAVA 基礎開發環境 vscode 搭建 來源 https://www.cnblogs.com/freewsf/p/7744728.html 對於使用 Visual Stu

轉-Windowsanaconda簡單使用教程

blank science size anaconda pycha pop p s alt popular 轉自:https://www.cnblogs.com/Dota-wiki/p/7871838.html Anaconda is a completely fr

填坑:Windows使用OpenSSL生成自簽證書(很簡單,一個晚上搞明白的,讓後來者少走彎路)

vat 都是 環境 csr 過程 環境變量 crypt 報錯 out 最近在學習中發現openssl 中有個坑,所有的教程都是openssl genrsa -des3 -out private.key 1024,但是產生的證書,npm start 之後就報錯如下: erro