我有一个非常基本的示例,即使用sdl2生成两个锯。它似乎正常工作,因为它听起来像我期望的那样。但是,当我在回调之间打印时间时,间隔远非我期望的偶数间隔。有这样的原因吗?
这是显示一些格式数据的输出,然后几十个间隔:
want:
freq : 48000
format : 33056
channels: 2
silence : 0
samples : 1024
size : 0
have:
freq : 48000
format : 33056
channels: 2
silence : 0
samples : 512
size : 4096
41
0
0
12
6
18
17
0
18
12
0
17
18
0
17
12
0
18
17
0
17
12
1
17
17
1
12
17
0
17
19
0
12
17
0
18
17
1
11
18
0
17
12
0
18
18
0
17
12
0
17
18
0
17
12
0
18
17
0
6
18
17
0
12
17
1
17
17
1
11
18
0
17
7
17
17
1
11
18
0
17
12
0
18
17
0
17
12
0
19
12
0
16
18
0
18
12
0
etc...
这是代码:
/*
* compiled with:
* gcc -Wall twosaw.c -o twosaw `sdl2-config --cflags --libs`
*/
#include <stdio.h>
#include "SDL.h"
#define AudSamRat 48000
#define AudBufLen 1024
Uint32 lastTime;
Uint32 thisTime;
float phaseL = -1;
float phaseR = -1;
void fillAudioBuffer(void *unused, Uint8 *byteStream, int byteStreamLength)
{
//printf("byteStreamLength: %dn", byteStreamLength); //-> 4096
float* floatStream = (float*) byteStream;
Uint32 floatStreamLength = byteStreamLength/4; //-> 1024
thisTime=SDL_GetTicks();
printf("%2dn", thisTime-lastTime);
lastTime =thisTime;
int i;
for (i = 0; i<floatStreamLength; i+=2)
{
floatStream[i] = phaseL; //left
floatStream[i+1] = phaseR; //right
phaseL += 0.01;
phaseR += 0.02;
if (phaseL > 1) phaseL = -1;
if (phaseR > 1) phaseR = -1;
}
}
void logSpec(SDL_AudioSpec *as)
{
printf(
" freq : %5dn"
" format : %5dn"
" channels: %5dn"
" silence : %5dn"
" samples : %5dn"
" size : %5dnn",
(int) as->freq,
(int) as->format,
(int) as->channels,
(int) as->silence,
(int) as->samples,
(int) as->size
);
}
int main(void)
{
SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER);
SDL_AudioSpec want, have;
SDL_AudioDeviceID AudDev;
SDL_zero(want);
want.freq = AudSamRat;
want.format = AUDIO_F32;
want.channels = 2;
want.samples = AudBufLen;
want.callback = fillAudioBuffer;
AudDev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
if (AudDev == 0) {
printf("Failed to open audio: %sn", SDL_GetError());
return 1;
} else {
printf("nwant:n");
logSpec(&want);
printf("have:n");
logSpec(&have);
if (have.format != want.format) // we let this one thing change.
printf("We didn't get Float32 audio format.n");
SDL_PauseAudioDevice(AudDev, 0); // start audio playing.
SDL_Delay(3000); // let the audio callback play some sound for 3 seconds.
SDL_CloseAudioDevice(AudDev);
}
SDL_Quit();
return 0;
}
sdl_getticks(),您用于定时,请在窗户的引擎盖下调用getTickCount()。getTickCount()的粒度约为10-25ms(取决于您的要求),这意味着此应用程序或多或少是无用的。
我确实要怀疑,您想通过查看何时调用回调来确定什么?如果您真的需要知道,请查看Windows下的QueryPerformanceCounter API。或者,如果您有幸使用现代编译器,请使用std :: Chrono。
使用QueryPerformanceCounter ...
// only need to do this part once
LARGE_INTEGER Freq;
QueryPerformanceFrequency(&Freq);
// Then, for timing
LARGE_INTEGER Time;
QueryPerformanceCounter(&Time);
double TimeInSeconds = double(Time.QuadPart) / double(Freq.QuadPart);
使用std :: Chrono
// at the start. chrono uses intervals, and wants a start time (I think)
auto StartTime = std::chrono::high_resolution_clock::now();
// during
std::chrono::duration<double> fsec = std::chrono::high_resolution_clock::now() - StartTime;
double TimeInSecondsSinceStart = fsec.count();