windowsAPI对电脑声卡信息的采集和播放(c++)实例程序(vs2017)

该程序是在vs2017上编写的,可以在其他版本上顺利运行

这是一个采用windowsAPI对声卡信息的采集和播放的c++程序,可以直接复制使用

有任何疑问,欢迎留言讨论

#readSoundCard.cpp

#include "readSoundCard.h"

static unsigned char buffer[BUFFER_SIZE] = { 0 };
static int buf_count = 0;

//播放存储为文件吧,在waveInProc里面做吧,采集一个,就收集一个
#define FILE_NAME "my_record.pcm"
#include <cstdio>
#include <list>

static void wait_a_bit()
{
#ifdef WIN32
	Sleep(1);
#else
	sleep_ms(1);
#endif
}

void CALLBACK usewindows_API::waveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
	LPWAVEHDR pwh = (LPWAVEHDR)dwParam1;

	if ((WIM_DATA == uMsg) && (buf_count<BUFFER_SIZE))  //uMsg == WIM_DATA 表示有新消息
	{
				
		int temp = BUFFER_SIZE - buf_count;
		if (temp > (pwh->dwBytesRecorded))
		{
			temp = pwh->dwBytesRecorded;
		}

		memcpy(buffer + buf_count, pwh->lpData, temp);
		voice_list.push_back(buffer + buf_count);///
		buf_count += temp;
		//直接写文件吧
	
		FILE *fp = fopen(FILE_NAME, "ab+");
		fwrite(pwh->lpData, 1, pwh->dwBufferLength, fp);
		
	
		waveInAddBuffer(hwi, pwh, sizeof(WAVEHDR));
		fclose(fp);
		//cout << "start record..." << endl;
	}
	
}

void CALLBACK usewindows_API::waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
	if (WOM_DONE == uMsg)
	{
		buf_count = BUFFER_SIZE;
	}
}


usewindows_API::Function::Function()
{
	wavform.wFormatTag = WAVE_FORMAT_PCM;
	wavform.nChannels = 1;//声道
	wavform.nSamplesPerSec = 44100;//8k,11.025k,22.05k,4101kHz
	wavform.wBitsPerSample = 16;//采样率的大小,WAVE_FORNAT_PCM 是 8 的整数倍
	wavform.nBlockAlign = (wavform.wBitsPerSample*wavform.nChannels) >> 3;//4;//以字节为单位的块对齐;2*16/8  
	wavform.nAvgBytesPerSec = wavform.nBlockAlign*wavform.nSamplesPerSec; //44100 * 16 * 2 / 8;//平均传输速度(byt/s)
	wavform.cbSize = 0;//额外空间
}

usewindows_API::Function::~Function()
{

}

void usewindows_API::Function::show_in_equipment()
{
	int nReturn = waveInGetNumDevs();
	cout<<"输入设备数目:"<< nReturn<<endl;
	for (int i = 0; i<nReturn; i++)
	{
		WAVEINCAPS wic;
		waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS));
		cout<<i<<" 设备名称:"<<wic.szPname<<"  ";
	}
	cout << endl;
}
void usewindows_API::Function::show_out_equipment()
{
	int nReturn = waveOutGetNumDevs();
	cout << "输出设备数目:" << nReturn << endl;
	for (int i = 0; i < nReturn; i++)
	{
		WAVEOUTCAPS woc;
		waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS));
		cout << i << " 设备名: " << woc.szPname << endl;
	}
}

void usewindows_API::Function::getSound()
{

	waveInOpen(&hWaveIn, WAVE_MAPPER, &wavform, (DWORD_PTR)waveInProc, 0, CALLBACK_FUNCTION);
	//指针句柄,WAVE_MAPPER:自动查找设备
	//处理函数,处理函数的参数列表
	WAVEINCAPS wic;
	waveInGetDevCaps((UINT_PTR)hWaveIn, &wic, sizeof(WAVEINCAPS));
	cout << "打开的输入设备:" << wic.szPname << endl;

	for (int i = 0; i < FRAGMENT_NUM; i++)
	{
		wh[i].lpData = new char[FRAGMENT_SIZE];//缓冲区存放的内容
		wh[i].dwBufferLength = FRAGMENT_SIZE;//缓冲区大小
		wh[i].dwBytesRecorded = 0;//缓冲区村的字节数
		wh[i].dwUser = NULL;
		wh[i].dwFlags = 0;
		wh[i].dwLoops = 1;
		wh[i].lpNext = NULL;
		wh[i].reserved = 0;

		waveInPrepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));
		waveInAddBuffer(hWaveIn, &wh[i], sizeof(WAVEHDR));
	}

	cout << "start record..." << endl;
	buf_count = 0;
	waveInStart(hWaveIn);	
	while (buf_count < BUFFER_SIZE)
	{
		wait_a_bit();
	}
	cout << "end record..." << endl;
	//
	waveInStop(hWaveIn);
	waveInReset(hWaveIn);
	for (int i = 0; i < FRAGMENT_NUM; i++)
	{
		waveInUnprepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));
		delete wh[i].lpData;
	}
	waveInClose(hWaveIn);
	//
	system("pause");//等待按键
	cout << endl;

}


void usewindows_API::Function::playSound()
{ 
	waveOutOpen(&hWaveOut, WAVE_MAPPER, &wavform, (DWORD_PTR)waveOutProc, 0, CALLBACK_FUNCTION);

	WAVEOUTCAPS woc;
	waveOutGetDevCaps((UINT_PTR)hWaveOut, &woc, sizeof(WAVEOUTCAPS));
	cout << "打开的输出设备:" << woc.szPname << endl;

	wavhdr.lpData = (LPSTR)buffer;
	wavhdr.dwBufferLength = BUFFER_SIZE;
	wavhdr.dwFlags = 0;
	wavhdr.dwLoops = 0;

	waveOutPrepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR));  

	cout<<"start play..."<<endl;
	buf_count = 0;
	waveOutWrite(hWaveOut, &wavhdr, sizeof(WAVEHDR));
	while (buf_count < BUFFER_SIZE)
	{
		wait_a_bit();
	}

	waveOutReset(hWaveOut);
	waveOutUnprepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR));
	waveOutClose(hWaveOut);

	cout << "end play..." << endl;
}

 

#readSoundCard.h

#ifndef _READ_SOUND_CARD_H__
#define _READ_SOUND_CARD_H__

#include <sdkddkver.h>
#include <tchar.h>

#include <Windows.h>
#include <mmsystem.h>
#include <iostream>
#include <list>

using std::cout;
using std::endl;

#pragma comment(lib,"winmm.lib")

#define BUFFER_SIZE (44100*16*2/8*5) //录制声音长度
#define FRAGMENT_SIZE 1024			 //缓存区大小
#define FRAGMENT_NUM 4				 //缓存区个数

extern std::list<unsigned char *> voice_list;

namespace usewindows_API
{
	
	void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
	void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
	class Function
	{
	public:
		Function();
		~Function();
		void show_in_equipment();
		void show_out_equipment();
		void getSound();
		void playSound();
	private:
		HWAVEIN hWaveIn;
		HWAVEOUT hWaveOut;
		WAVEFORMATEX wavform;
		WAVEHDR wavhdr;
		WAVEHDR wh[FRAGMENT_NUM];
	};
}

#endif

 

#main.cpp

#include "readSoundCard.h"


std::list<unsigned char *> voice_list;

int main(int argc, char *argv[])//cmd
{
	usewindows_API::Function run;
	run.show_in_equipment();
	run.getSound();
	run.show_out_equipment();
	run.playSound();
	return 0;
}


 

  • 7
    点赞
  • 10
    评论
  • 21
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值