sndio sio_onmove没有回电。

时间:2016-06-19 04:42:38

标签: audio openbsd

我正在尝试编写一个将音频复制到音频输出的全双工测试。 sio_onmove没有被调用。我不知道为什么。到目前为止,这是我的代码:

#include <stdio.h>
#include <stdlib.h>

#include <sndio.h>

unsigned char buf[0xffff];

struct sio_hdl *hdl;

void cb(void *arg, int delta) {
 int l;
 printf("call %d\n", delta);
 for(;;) {
  l = sio_read(hdl, buf, delta);
  if(l==0) break;
  sio_write(hdl, buf, l);
 }
}

int main(void) {
 int m, i;
 struct sio_par par;
 struct sio_cap cap;

 hdl = sio_open("rsnd/0", SIO_PLAY | SIO_REC , 1);


 sio_getcap(hdl, &cap);

 sio_initpar( &par);

 par.bits = cap.enc[0].bits;
 par.bps = cap.enc[0].bps;
 par.sig = cap.enc[0].sig;
 par.le = cap.enc[0].le;
 par.msb = cap.enc[0].msb;
 par.rchan=cap.rchan[0];
 par.pchan=cap.pchan[0];
 par.rate =cap.rate[0];

 par.appbufsz = 1024;

 sio_setpar(hdl, &par);

 sio_onmove(hdl, cb, NULL);

 sio_start(hdl);

 for(;;)
  sleep(1);

}

我正在初始化rsnd / 0进行录制和播放。我正在从getcap调用初始化的参数。然后我将cb设置为onmove的回调。然后我开始音频。从那里我循环永远无所事事

1 个答案:

答案 0 :(得分:1)

如果使用非阻止i / o,则会从sio_onmove()调用sio_revents()回叫,或阻止sio_read()sio_write()。 如上所述,程序调用{​​{1}},从不调用回调。

AFAIU,要进行全双工测试,您可以使用阻塞i / o(设置为sleep(1)函数的最后一个参数)并执行以下步骤:

  1. 调用sio_open()初始化sio_initpar()结构,就像您一样
  2. sio_par结构
  3. 中设置首选参数
  4. 致电sio_par将其提交给设备。通过服务器公开的设备(例如“snd / 0”)将接受任何参数,而原始设备(例如“rsnd / 0”)选择接近硬件支持的任何参数。
  5. 调用sio_setpar()获取设备接受的参数,这是获取设备缓冲区大小所必需的
  6. 可能会检查您的程序是否可以使用
  7. 致电sio_getpar()
  8. 使用sio_start()编写par.bufsz个样本来填充播放缓冲区。这对应于:sio_write()字节。
  9. 在此阶段,设备启动,您可以使用以下伪代码执行主循环:

    par.bufsz * par.pchan * par.bps

    纯音频节目不需要sio_onmove()回叫。它仅用于将非音频事件(例如视频,midi消息)同步到音频流。