2016-06-19 9 views
0

Я пытаюсь написать тест fullduplex, который копирует аудио в аудио. sio_onmove не вызывается. Понятия не имею почему. Вот мой код:sndio 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 как callback для onmove. Затем я начинаю аудио. Оттуда я зациклюсь ничего не делая

ответ

1

sio_onmove() обратного вызова вызывается либо из sio_revents() если неблокирующая I/O используется или от блокировки sio_read() или sio_write(). Как и выше, программные вызовы sleep(1), обратный вызов никогда не вызывается.

AFAIU, чтобы сделать полный дуплекс теста, вы можете использовать блокирование ввода/вывод (комплект до 0 последнего аргумента функции sio_open()) и выполните следующие действия:

  1. вызова sio_initpar() для инициализации sio_par структура, как и вы,
  2. укажите свои предпочтительные параметры в структуре sio_par
  3. позвонить sio_setpar(), чтобы отправить их на устройство. устройства, открытые через сервер (например, «snd/0»), будут принимать любые параметры, в то время как необработанные устройства (например, «rsnd/0») выбирают что-то близко к тому, что поддерживает оборудование.
  4. вызов sio_getpar(), чтобы получить параметры, принятые устройства, это необходимо, чтобы получить размер буфера устройства
  5. возможно проверить, если они доступны по программе
  6. вызова sio_start()
  7. прокачать игру буфер пути записи par.bufsz образцов с sio_write(). Это соответствует: par.bufsz * par.pchan * par.bps байтам.

На этом этапе начинается устройство, и вы могли бы сделать основной петлю, как с помощью следующего псевдокода:

unsigned char *data; 
size_t n, todo, blksz; 

blksz = par.round * par.rchan * par.bps; 
for (;;) { 
     /* read one block */ 
     data = buf; 
     todo = blksz; 
     while (todo > 0) { 
       n = sio_read(hdl, data, todo); 
       if (n == 0) 
         errx(1, "failed"); 
       todo -= n; 
       data += n; 
     } 
     /* write one block */ 
     n = sio_write(hdl, buf, blksz); 
     if (n != blksz) 
       errx(1, "failed"); 
} 

sio_onmove() обратного вызова не требуется для чистых звуковых программ. Полезно синхронизировать не аудио-события (например, видео, midi-сообщения) с аудиопотоком.