我正在编写一个使用 SDL_Audio 并动态产生声音的程序,但我发现我的实现不是非常敏感,延迟从 .3 到 .5 秒不等。
我怀疑我在声卡需要数据之前很久就发出了声音。我的解决方案是在第一次请求音频时触发声音产生。为此,我添加了一个函数指针,该指针最初设置为一个素数函数
所以本质上我有一个静态成员函数通过成员函数指针调用成员函数,我遇到了编译问题。
寻找通过函数指针调用成员函数的正确语法。
我有以下重现我的问题的测试程序。
/*
* testcallback.cpp
*
* Created on: Apr 20, 2023
* Author: phil
*/
#include <SDL2/SDL.h>
#include <fstream>
#include <iostream>
class AudioCallbackTest
{
public:
AudioCallbackTest()
{
SDL_Init(SDL_INIT_AUDIO);
SDL_AudioSpec desiredSpec = {0};
desiredSpec.format = AUDIO_S16SYS;
desiredSpec.channels = 1;
desiredSpec.freq = 44100;
desiredSpec.samples = 256;
desiredSpec.callback = audioCallbackWrap;
desiredSpec.userdata = this;
m_hwDevice = SDL_OpenAudioDevice(nullptr, false, &desiredSpec, NULL, 0);
if (m_hwDevice == 0)
{
std::cout << "SDL_OpenAudioDevice failed: SDL error [" << SDL_GetError() << "]" << std::endl;
return;
}
}
static void audioCallbackWrap(void *_instance, Uint8* _stream, int _length)
{
// ((AudioCallbackTest*)_instance)->m_audioCallback(_stream, _length);
((AudioCallbackTest*)_instance)->*m_audioCallback(_stream, _length);
}
void audioCallback(Uint8* stream, int len)
{
std::cout << "audio callback" << std::endl;
}
void primeAudioCallback(Uint8* stream, int len)
{
std::cout << "prime callback" << std::endl;
m_audioCallback = &AudioCallbackTest::audioCallback;
}
private:
SDL_AudioDeviceID m_hwDevice;
void (AudioCallbackTest::*m_audioCallback)(uint8_t *stream, int len) = &AudioCallbackTest::primeAudioCallback;
};
注意静态函数中的注释行。在第一种形式中我得到了错误
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o testcallback.o ../testcallback.cpp
../testcallback.cpp: In static member function ‘static void AudioCallbackTest::audioCallbackWrap(void*, Uint8*, int)’:
../testcallback.cpp:35:65: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((AudioCallbackTest*)_instance)->AudioCallbackTest::m_audioCallback (...)’, e.g. ‘(... ->* ((AudioCallbackTest*)_instance)->AudioCallbackTest::m_audioCallback) (...)’
35 | ((AudioCallbackTest*)_instance)->m_audioCallback(_stream, _length);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
使用第二种形式我得到以下错误
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o testcallback.o ../testcallback.cpp
../testcallback.cpp: In static member function ‘static void AudioCallbackTest::audioCallbackWrap(void*, Uint8*, int)’:
../testcallback.cpp:37:51: error: invalid use of member ‘AudioCallbackTest::m_audioCallback’ in static member function
37 | ((AudioCallbackTest*)_instance)->*m_audioCallback(_stream, _length);
| ^~~~~~~~~~~~~~~
../testcallback.cpp:51:35: note: declared here
51 | void (AudioCallbackTest::*m_audioCallback)(uint8_t *stream, int len) = &AudioCallbackTest::primeAudioCallback;
| ^~~~~~~~~~~~~~~
编译器版本为GNU C++17 (Ubuntu 11.3.0-1ubuntu1~22.04) version 11.3.0 (x86_64-linux-gnu) IDE 版本:2023-03 (4.27.0) CDT 是版本:11.1.0.202212091724
我尝试过各种语法
This->m_audioCallback(_stream, _length);
This->*m_audioCallback(_stream, _length);
(This->*m_audioCallback)(_stream, _length);
This->*m_audioCallback(_stream, _length);
(*This).*m_audioCallback(_stream, _length);
我用谷歌搜索了错误信息。
我在谷歌上搜索了“通过成员函数指针调用成员的静态成员”,找到了关于如何调用成员函数和大量函数指针示例的搜索结果,但没有一个符合要求。
我假设有一个正确的语法。