nonblocking

This commit is contained in:
Sébastien Bourdeauducq 2024-12-26 17:33:59 +08:00
parent cd66e84cee
commit 312ab52eca

View File

@ -4,6 +4,7 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <sndio.h> #include <sndio.h>
#include <poll.h>
#include <math.h> #include <math.h>
#include "imgui.h" #include "imgui.h"
@ -24,7 +25,7 @@ static void dsp_thread()
struct sio_hdl *hdl; struct sio_hdl *hdl;
struct sio_par par; struct sio_par par;
hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0); hdl = sio_open(SIO_DEVANY, SIO_PLAY, 1);
if(hdl == nullptr) { if(hdl == nullptr) {
std::cerr << "failed to open sound device" << std::endl; std::cerr << "failed to open sound device" << std::endl;
return; return;
@ -35,11 +36,17 @@ static void dsp_thread()
par.pchan = SND_PCHAN; par.pchan = SND_PCHAN;
par.rate = SND_RATE; par.rate = SND_RATE;
par.le = SIO_LE_NATIVE; par.le = SIO_LE_NATIVE;
par.xrun = SIO_ERROR;
if(!sio_setpar(hdl, &par)) { if(!sio_setpar(hdl, &par)) {
std::cerr << "failed to set sound device parameters" << std::endl; std::cerr << "failed to set sound device parameters" << std::endl;
sio_close(hdl); sio_close(hdl);
return; return;
} }
if(!sio_getpar(hdl, &par)) {
std::cerr << "failed to get back sound device parameters" << std::endl;
sio_close(hdl);
return;
}
if(!sio_start(hdl)) { if(!sio_start(hdl)) {
std::cerr << "failed to start sound device" << std::endl; std::cerr << "failed to start sound device" << std::endl;
@ -48,18 +55,33 @@ static void dsp_thread()
} }
uint32_t phase = 0; uint32_t phase = 0;
int16_t buf[SND_BUFLEN*SND_PCHAN];
int16_t buf_out[SND_BUFLEN*SND_PCHAN];
size_t buf_out_idx = SND_BUFLEN*SND_PCHAN;
nfds_t nfds = sio_nfds(hdl);
struct pollfd pfd[nfds];
while(!shutdown_threads) { while(!shutdown_threads) {
uint32_t ftw = frequency*(float)UINT32_MAX/SND_RATE; sio_pollfd(hdl, pfd, POLLOUT);
for(int i=0;i<SND_BUFLEN;i++) { poll(pfd, nfds, INFTIM);
buf[2*i] = buf[2*i+1] = (INT16_MAX-1)*sin(phase*2.0f*(float)M_PI/(float)UINT32_MAX); int revents = sio_revents(hdl, pfd);
phase += ftw;
} if(revents & POLLOUT) {
if(!sio_write(hdl, buf, SND_BUFLEN*(SND_BITS/8)*SND_PCHAN)) { uint32_t ftw = frequency*(float)UINT32_MAX/SND_RATE;
std::cerr << "failed to write to sound device" << std::endl; if(buf_out_idx == SND_BUFLEN*SND_PCHAN) {
sio_stop(hdl); for(int i=0;i<SND_BUFLEN;i++) {
sio_close(hdl); buf_out[2*i] = buf_out[2*i+1] = (INT16_MAX-1)*sin(phase*2.0f*(float)M_PI/(float)UINT32_MAX);
return; phase += ftw;
}
buf_out_idx = 0;
}
size_t written = sio_write(hdl, &buf_out[buf_out_idx], sizeof(buf_out) - buf_out_idx*sizeof(buf_out[0]));
buf_out_idx += written/sizeof(buf_out[0]);
if(!written) {
std::cerr << "failed to write to sound device" << std::endl;
sio_stop(hdl);
sio_close(hdl);
return;
}
} }
} }