0

(我在这里的第一个问题,所以我希望我没有踩到任何脚趾 - 我尝试搜索我的问题,但我没有看到任何似乎适用的东西;但它可能有,我只是不明白我正在看。)

我以前从来不需要处理音频,所以我感到有点失落。我需要做的很简单;监控来自麦克风的实时馈送,当音量超过一定水平时,做一些事情。我已经处理好了做的事情,但是我所有试图理解音频的谷歌让我比开始时更加困惑。

如果它有所作为;我正在使用 Visual Studio Express 2012。

到目前为止,这是我的代码:

#include <windows.h>
#include <queue>
//I figured I could put the sound info
//in a queue and push it through checking
//the volume as I went.

using namespace std;

//For this code, the below is just for debug messages
//It plays a more important role in the full code.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow);

//This seemed to be a decent way to make sure I could read in
//from the audio.
MMRESULT IsFormatSupported(LPWAVEFORMATEX pwfx, UINT uDeviceID) 
{ 
    return (waveOutOpen( 
        NULL,                 // ptr can be NULL for query 
        uDeviceID,            // the device identifier 
        pwfx,                 // defines requested format 
        NULL,                 // no callback 
        NULL,                 // no instance data 
        WAVE_FORMAT_QUERY));  // query only, do not open device 
} 

int main()
{
    UINT wReturn; 
    const int NUMPTS = 11025 * 10;   // 10 seconds
    short int waveIn[NUMPTS];
    queue<short int*> my_queue;
    WAVEFORMATEX pcmWaveFormat; 

    // Set up WAVEFORMATEX for 11 kHz 8-bit mono. 

    pcmWaveFormat.wFormatTag = WAVE_FORMAT_PCM; 
    pcmWaveFormat.nChannels = 1; 
    pcmWaveFormat.nSamplesPerSec = 11025L; 
    pcmWaveFormat.nAvgBytesPerSec = 11025L; 
    pcmWaveFormat.nBlockAlign = 1; 
    pcmWaveFormat.wBitsPerSample = 8; 
    pcmWaveFormat.cbSize = 0;
    MMRESULT result = 0;
    HWAVEIN microHandle;
    WAVEHDR waveHeader;
    // See if format is supported by any device in system. 

    wReturn = IsFormatSupported(&pcmWaveFormat, WAVE_MAPPER); 
    // Report results. 
    if (wReturn == 0) 
    {
        //To make sure I can actually get the audio:
        //MessageBox(NULL, "11 kHz 8-bit mono IS supported.",
        //"", MB_ICONINFORMATION); 
    }
    else if (wReturn == WAVERR_BADFORMAT) 
    {
    MessageBox(NULL, "11 kHz 8-bit mono NOT supported.",
        "", MB_ICONINFORMATION); 
    return -2;
    }
    else 
    {
    MessageBox(NULL, "Error opening waveform device.",
        "Error", MB_ICONEXCLAMATION); 
    return -3;
    }

result = waveInOpen(&microHandle, WAVE_MAPPER,
         &pcmWaveFormat, 0L, 0L, WAVE_FORMAT_DIRECT); 
    // Set up and prepare header for input
    waveHeader.lpData = (LPSTR)waveIn;
    waveHeader.dwBufferLength = NUMPTS*2;
    waveHeader.dwBytesRecorded=0;
    waveHeader.dwUser = 0L;
    waveHeader.dwFlags = 0L;
    waveHeader.dwLoops = 0L;
    waveInPrepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR));

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

    waveInStart(microHandle);
    //In theory, this should stop after ten seconds,
    //as set by NUMPTS - but doesn't.
do {} while (waveInUnprepareHeader(microHandle,
    &waveHeader, sizeof(WAVEHDR))==WAVERR_STILLPLAYING);
MessageBox(NULL, "Done Recording", "", MB_ICONINFORMATION); 

    waveInClose(microHandle);

    cout << "Press ENTER to continue...";
    cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    return 0;
}

我还必须手动进入项目属性并在链接器->输入->附加依赖项下添加 Winmm.lib

我不确定从这里去哪里。我知道我需要检查音频流的音量,但我不需要存储它以供以后使用,这就是我放置#include 队列的原因。但我什至不知道在队列中存储什么或如何阅读它,所以我不完全确定这是否合适。

如果有人对音频初学者有建议、答案或好的资源,我将不胜感激。

4

2 回答 2

0

音频样本将在您的 waveIn 缓冲区中。不需要队列,只需检查 waveIn 中的值。

您使用了 8 位/样本。如果这真的是你想要的 waveIn 缓冲区是错误的类型。它应该是字节,而不是短裤。但是 16 位/样本是更好的选择:8 位数据是一种有趣的格式,需要额外的转换。如果每个样本使用 16 位,则普通有符号算术将用于比较样本值。

于 2013-07-24T20:56:58.500 回答
0

如果您使用 16 位/样本,则值将接近 0 以表示静音。响亮的音调会产生具有正负峰值的正弦波 (+32K ... - 32K)。

短卷=绝对(样本);

投球不是那么容易。从技术上讲,它是正弦波过零之间时间的补充。有一种数学算法 (FFT) 可以计算音调谱。

要更熟悉这些概念,请获取音频编辑器并使用它。它们显示来自 waveIn 或 WAV 文件的数据。其中有无数可用作共享软件。

于 2013-07-24T23:38:20.033 回答