C++ 如何录制麦克风直到没有声音?

C++ 如何录制麦克风直到没有声音?,c++,winapi,voip,voice-recording,C++,Winapi,Voip,Voice Recording,我创建了两个函数: -记录麦克风的人 -播放麦克风声音的人 它会将麦克风录制3秒钟 #include <iostream> #include <Windows.h> #include <vector> using namespace std; #pragma comment(lib, "winmm.lib") short int waveIn[44100 * 3]; void PlayRecord(); void StartRecord() { co

我创建了两个函数: -记录麦克风的人 -播放麦克风声音的人

它会将麦克风录制3秒钟

#include <iostream>
#include <Windows.h>
#include <vector>
using namespace std;

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

 short int waveIn[44100 * 3];

void PlayRecord();

void StartRecord()
{
const int NUMPTS = 44100 * 3;   // 3 seconds
int sampleRate = 44100;  
// 'short int' is a 16-bit type; I request 16-bit samples below
                         // for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit     types

 HWAVEIN      hWaveIn;
 MMRESULT result;

 WAVEFORMATEX pFormat;
 pFormat.wFormatTag=WAVE_FORMAT_PCM;     // simple, uncompressed format
 pFormat.nChannels=1;                    //  1=mono, 2=stereo
 pFormat.nSamplesPerSec=sampleRate;      // 44100
 pFormat.nAvgBytesPerSec=sampleRate*2;   // = nSamplesPerSec * n.Channels *    wBitsPerSample/8
 pFormat.nBlockAlign=2;                  // = n.Channels * wBitsPerSample/8
 pFormat.wBitsPerSample=16;              //  16 for high quality, 8 for telephone-grade
 pFormat.cbSize=0;

 // Specify recording parameters

 result = waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat,
        0L, 0L, WAVE_FORMAT_DIRECT);

  WAVEHDR      WaveInHdr;
 // Set up and prepare header for input
  WaveInHdr.lpData = (LPSTR)waveIn;
  WaveInHdr.dwBufferLength = NUMPTS*2;
  WaveInHdr.dwBytesRecorded=0;
  WaveInHdr.dwUser = 0L;
  WaveInHdr.dwFlags = 0L;
  WaveInHdr.dwLoops = 0L;
  waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

 // Insert a wave input buffer
  result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));


 // Commence sampling input
  result = waveInStart(hWaveIn);


 cout << "recording..." << endl;

  Sleep(3 * 1000);
 // Wait until finished recording

 waveInClose(hWaveIn);

 PlayRecord();
}

void PlayRecord()
{
const int NUMPTS = 44100 * 3;   // 3 seconds
int sampleRate = 44100;  
// 'short int' is a 16-bit type; I request 16-bit samples below
                            // for 8-bit capture, you'd    use 'unsigned char' or 'BYTE' 8-bit types

HWAVEIN  hWaveIn;

WAVEFORMATEX pFormat;
pFormat.wFormatTag=WAVE_FORMAT_PCM;     // simple, uncompressed format
pFormat.nChannels=1;                    //  1=mono, 2=stereo
pFormat.nSamplesPerSec=sampleRate;      // 44100
pFormat.nAvgBytesPerSec=sampleRate*2;   // = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.nBlockAlign=2;                  // = n.Channels * wBitsPerSample/8
pFormat.wBitsPerSample=16;              //  16 for high quality, 8 for telephone-grade
pFormat.cbSize=0;

// Specify recording parameters

waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat, 0L, 0L, WAVE_FORMAT_DIRECT);

WAVEHDR      WaveInHdr;
// Set up and prepare header for input
WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = NUMPTS*2;
WaveInHdr.dwBytesRecorded=0;
WaveInHdr.dwUser = 0L;
WaveInHdr.dwFlags = 0L;
WaveInHdr.dwLoops = 0L;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

HWAVEOUT hWaveOut;
cout << "playing..." << endl;
waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);
waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); // Playing the data
Sleep(3 * 1000); //Sleep for as long as there was recorded

waveInClose(hWaveIn);
waveOutClose(hWaveOut);
}

int main()
{
 StartRecord();
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
#pragma注释(lib,“winmm.lib”)
短int波[44100*3];
作废播放记录();
void StartRecord()
{
常量int NUMPTS=44100*3;//3秒
int-sampleRate=44100;
//“short int”是一种16位类型;我需要下面的16位示例
//对于8位捕获,您将使用“unsigned char”或“BYTE”8位类型
华脉华脉;
MMRESULT结果;
波格式;
pFormat.wFormatTag=WAVE\u FORMAT\u PCM;//简单的未压缩格式
pFormat.nChannels=1;//1=单声道,2=立体声
pFormat.nSamplesPerSec=sampleRate;//44100
p格式nAvgBytesPerSec=采样器*2;/=nSamplesPerSec*n.通道*wBitsPerSample/8
p格式nblockallign=2;//=n.通道*wBitsPerSample/8
pFormat.wBitsPerSample=16;//16表示高质量,8表示电话等级
pFormat.cbSize=0;
//指定录制参数
结果=waveInOpen(&HwaVene)、WAVE_映射器和pFormat,
0L、0L、WAVE\u格式\u DIRECT);
WAVEHDR WaveInHdr;
//设置并准备输入标题
WaveInHdr.lpData=(LPSTR)waveIn;
WaveInHdr.dwBufferLength=NUMPTS*2;
WaveInHdr.dwBytesRecorded=0;
WaveInHdr.dwUser=0升;
WaveInHdr.dwFlags=0L;
WaveInHdr.dwLoops=0升;
WaveInPrepreaheader(hWaveIn和WaveInHdr,sizeof(WAVEHDR));
//插入一个波形输入缓冲区
结果=waveInAddBuffer(hWaveIn,&WaveInHdr,sizeof(WAVEHDR));
//开始采样输入
结果=waveInStart(静脉);

cout我建议您通过DirectShow进行此操作。您应该创建麦克风、SampleGrabber、音频编码器和文件编写器的实例。您的图形应该如下所示:

const double threshold = 50;    // Whatever threshold you need
const int max_samples = 10000;  // The representative running average size

double average = 0;             // The running average
int sample_count = 0;           // When we are building the average

while( sample_count < max_samples || average > threshold ) {
    // New sample arrives, stored in 'sample'

    // Adjust the running absolute average
    if( sample_count < max_samples ) sample_count++;
    average *= double(sample_count-1) / sample_count;
    average += std::abs(sample) / sample_count;
}
麦克风->采样仪->音频编码器->文件编写器


每个样品都经过采样仪,您可以读取所有原始样品,并检查是否应继续记录。这是您和双方记录和检查其内容的最佳方式。

因为声音是一种波,它在高压和低压之间振荡。该波形通常记录为正数和负数,0为b如果你取信号的绝对值并保持运行平均值,就足够了

应在足够长的时间内计算平均值,以考虑适当的沉默量。一种非常便宜的方法来估算运行平均值,如下所示:

const double threshold = 50;    // Whatever threshold you need
const int max_samples = 10000;  // The representative running average size

double average = 0;             // The running average
int sample_count = 0;           // When we are building the average

while( sample_count < max_samples || average > threshold ) {
    // New sample arrives, stored in 'sample'

    // Adjust the running absolute average
    if( sample_count < max_samples ) sample_count++;
    average *= double(sample_count-1) / sample_count;
    average += std::abs(sample) / sample_count;
}
调整
threshold
max\u samples
将控制对弹出和点击的敏感度,而
max\u silence\u samples
可让您控制停止录制前允许的静音量


毫无疑问,有更多的技术方法可以实现你的目标,但首先尝试简单的方法总是好的。看看你是如何做到这一点的。

没有“没有声音”这样的东西.相反,声级会在一段时间内下降到某个阈值以下。这就是我的意思。那么我如何检查声级?可能是同一张海报的重复。@KenWhite不是,因为在这个线程中,我试图将1个函数拆分为2个,而在这里我试图更改它。。。“开始录音,我对着麦克风说了一个字,当沉默一两秒钟时,它就会停止录音或其他什么?”这与“录音,直到麦克风没有输入”不一样吗?"写入文件->打开文件以获取音频并在计算机上播放要慢得多,特别是如果我想将其用于VOIP…这是您的全部选择。您可以通过默认DirectSound设备进行渲染,或将其渲染为空渲染器,或将其写入文件,等等。这是您的全部选择。我建议您写入文件,因为您的代码可以我的代码没有写入到文件中,播放函数得到缓冲区并播放它,使它更快…对不起,阿米特,我读错了。好吧,你仍然可以渲染它:麦克风->采样抓取器->默认DirectSound设备。你可以根据自己的意愿暂停/启动/停止图形。谢谢!但是DirectShow中有选项吗,比如使用WINAPI波函数,通过缓冲区录制和播放?