使用 OpenAL 和 VC++ 在 winforms 中绘制音频波形

Drawing audio waveform in winforms using OpenAL and VC++

我有一个关于信号处理的研究项目,我有义务记录来自某些来源(例如麦克风)的声音并在两个图表上显示波形及其 FFT。我无法提供将缓冲区显示到图表中而不拖延整个程序的功能。

因为我还不知道 C#,所以我选择了 C++/CLI 下的 Winforms 和 OpenAL 来进行声音捕捉(声音处理方面的经验为 0,这在几个线程中被推荐,我的团队的其他成员正在使用它所以我有点不得不使用它)。我已经有了选择声音设备并将声音录制到缓冲区中的代码。我知道下面的 while 循环正在拖延程序。我正在考虑使用多线程,但不知道如何使用它。或者事件...

这是捕获开始的代码,在一些按钮事件中。

int go = 0;

const int SRATE = 44100;
const int SSIZE = 1024;
ALCdevice *hydromike;

ALbyte buffer[22050];
ALint sample;

some_event {
const char* diwajs = (msclr::interop::marshal_as<std::string>(item)).c_str();
        hydromike = alcCaptureOpenDevice(diwajs, SRATE, AL_FORMAT_MONO16, SSIZE);
        alcCaptureStart(hydromike);

        buffering(); //function call for starting the buffer
}

void buffering(void)
{
while (go) {

    alcGetIntegerv(hydromike, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &sample);
    alcCaptureSamples(hydromike, (ALCvoid *)buffer, sample);

}
}

void drw(void)
{
chart1->Series["Bufor"]->Points->Clear();
for (int i = 0; i < 22050; i++)
{
    chart1->Series["Bufor"]->Points->AddXY(i, (int)buffer[i]);
}
}

我希望它像这样工作:https://www.youtube.com/watch?v=q9cRZuosrOs

我设法完成了代码,问题是 UI 和 OpenAL 线程相互干扰,导致应用程序冻结。在另一个线程中启动缓冲并设置信号量解决了问题。

static Semaphore^ drawingSem = gcnew Semaphore(1, 1);
    Thread^ oThread;
alcCaptureStart(hydromike);

            oThread = gcnew Thread(gcnew ThreadStart(buffering));
            oThread->Start();

static void buffering()
{
while (go) {
    drawingSem->WaitOne();
    alcGetIntegerv(hydromike, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), buffer);

    alcCaptureSamples(hydromike, (ALCvoid *)buffer, sample*2);

    drawingSem->Release();


}
}

void MyForm::drw()
{

drawingSem->WaitOne();

chart1->Series["Bufor"]->Points->Clear();

for (int i = 0; i < bufsize; i++)
{
    chart1->Series["Bufor"]->Points->AddXY(i, (int)buffer[i]);
}
drawingSem->Release();
}

private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {

drw();

}