该程序是在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;
}