直接声音:如何从小缓冲区读取捕获的数据?

时间:2016-11-03 16:39:27

标签: c++ audio wav directsound

我试图从麦克风捕获浮点PCM数据的波形。该应用程序每个周期仅要求少量样本(对于20' 000Hz,帧大小为0.003s,它将要求60个样本)

我想根据应用感兴趣的ms数来设置缓冲区大小,但似乎dwBufferBytes必须是一定的大小。相反,我将它设置为nAvgBytesPerSec,每次只锁定/复制60个样本(即使可以读取更多数据)

这是一种有效的方法还是有不同的方法来限制声音驱动程序?有没有办法减少缓冲区的大小只给我应用程序请求的数据量?我不想听到很多声音     数据,如果应用程序只需要60个值。

使用这种方法,如果缓冲区赶上我的(慢)读取光标,我肯定会遇到问题。

    unsigned short channelNum = 2;
    unsigned short bitsPerSample = 32;
    unsigned long sampleRate = 20000;
    unsigned short blockAlign = (channelNum * bitsPerSample) / 8;
    unsigned long avgBytesPerSec = sampleRate * blockAlign;

    WAVEFORMATEX wfx = { WAVE_FORMAT_IEEE_FLOAT, channelNum, sampleRate, avgBytesPerSec, blockAlign, bitsPerSample, 0 };

    unsigned int mSampleBufferSize = 60; // 1400

    DSCBUFFERDESC bufferDesc;
    bufferDesc.dwSize = sizeof(DSCBUFFERDESC);
    bufferDesc.dwFlags = 0;
    bufferDesc.dwBufferBytes = wfx.nAvgBytesPerSec;
    bufferDesc.dwReserved = 0;
    bufferDesc.lpwfxFormat = &wfx;
    bufferDesc.dwFXCount = 0;
    bufferDesc.lpDSCFXDesc = NULL;

    IDirectSoundCaptureBuffer *buffer = 0;
    bool bufferRunning = false;
    if (directSound && capture)
    {
        hr = capture->CreateCaptureBuffer(&bufferDesc, &buffer, NULL);
        if (FAILED(hr))
           std::cout << "SampleThread() -- Error creating DirectSoundCaptureBuffer " << endl;
        else
        {
            hr = buffer->Start(DSCBSTART_LOOPING);
            if (SUCCEEDED(hr)) {
                bufferRunning = true;
            }
        }
    }

    void* primaryBuffer = NULL;
    unsigned long primaryBufferSizeBytes = 0;
    void* secondaryBuffer = NULL;
    unsigned long secondaryBufferSize = 0;
    bool mStopExecution = false;
    unsigned long lastReadPosition = 0;


    if (directSound && capture && buffer)
    {
        while (!mStopExecution)
        {
            DWORD readPos;
            WORD remainingSize = 0;
            DWORD capturePos;
            hr = buffer->GetCurrentPosition(&capturePos, &readPos);
            if (FAILED(hr))
            {
                cout << "SampleThread() -- Error GetCurrentPosition" << endl;
                return 0;
            }


            buffer->Lock(lastReadPos, mSampleBufferSize, &primaryBuffer, &primaryBufferSizeBytes, &secondaryBuffer, &secondaryBufferSize, NULL);
            memcpy(mBuffer, (float*)primaryBuffer, primaryBufferSizeBytes / sizeof(float));

             // .... copy secondary buffer
             hr = buffer->Unlock(primaryBuffer, primaryBufferSizeBytes, secondaryBuffer, secondaryBufferSize);
            lastReadPosition = (lastReadPosition + mSampleBufferSize) % bufferDesc.dwBufferBytes;
        }
    }

0 个答案:

没有答案
相关问题