Changeset 4206:76162667542c in roaraudio


Ignore:
Timestamp:
08/19/10 22:37:56 (14 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

better support for latency stuff

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • include/libroar/vs.h

    r4204 r4206  
    4242 
    4343typedef struct roar_vs roar_vs_t; 
     44typedef signed long int roar_mus_t; 
    4445 
    4546/* return readable string descriping the problem */ 
     
    125126#define ROAR_VS_BACKEND_MEAN    -3 
    126127 
    127 ssize_t roar_vs_latency(roar_vs_t * vss, int backend, int * error); 
     128ssize_t roar_vs_position(roar_vs_t * vss, int backend, int * error); 
     129 
     130roar_mus_t roar_vs_latency(roar_vs_t * vss, int backend, int * error); 
    128131 
    129132/* set pause flag 
  • libroar/vs.c

    r4199 r4206  
    3939#define FLAG_STREAM   0x0001 
    4040#define FLAG_NONBLOCK 0x0002 
     41#define FLAG_BUFFERED 0x0004 
    4142 
    4243#define _initerr()  do { errno = 0; roar_err_clear(); } while(0) 
     
    5152 struct roar_stream       stream; 
    5253 struct roar_vio_calls    vio; 
     54 struct roar_audio_info   info; 
     55 size_t                   readc, writec; 
     56 int                      mixerid; 
     57 int                      first_primid; 
    5358}; 
     59 
     60static int _roar_vs_find_first_prim(roar_vs_t * vss); 
    5461 
    5562const char * roar_vs_strerr(int error) { 
     
    93100 memset(vss, 0, sizeof(roar_vs_t)); 
    94101 
     102 vss->mixerid      = -1; 
     103 vss->first_primid = -1; 
     104 
    95105 return vss; 
    96106} 
     
    130140 
    131141int roar_vs_stream(roar_vs_t * vss, const struct roar_audio_info * info, int dir, int * error) { 
     142 struct roar_stream_info sinfo; 
    132143 int ret; 
    133144 
     
    138149 
    139150 _initerr(); 
     151 
     152 if ( info != &(vss->info) ) 
     153  memcpy(&(vss->info), info, sizeof(struct roar_audio_info)); 
    140154 
    141155 ret = roar_vio_simple_new_stream_obj(&(vss->vio), vss->con, &(vss->stream), 
     
    149163 } 
    150164 
     165 if ( roar_stream_get_info(vss->con, &(vss->stream), &sinfo) != -1 ) { 
     166  vss->mixerid = sinfo.mixer; 
     167  _roar_vs_find_first_prim(vss); 
     168 } 
     169 
    151170 vss->flags |= FLAG_STREAM; 
    152171 
     
    156175roar_vs_t * roar_vs_new_simple(const char * server, const char * name, int rate, int channels, int codec, int bits, int dir, int * error) { 
    157176 roar_vs_t * vss = roar_vs_new(server, name, error); 
    158  struct roar_audio_info info; 
    159177 int ret; 
    160178 
     
    162180  return NULL; 
    163181 
    164  memset(&info, 0, sizeof(info)); 
    165  
    166  info.rate     = rate; 
    167  info.channels = channels; 
    168  info.codec    = codec; 
    169  info.bits     = bits; 
    170  
    171  ret = roar_vs_stream(vss, &info, dir, error); 
     182 memset(&(vss->info), 0, sizeof(vss->info)); 
     183 
     184 vss->info.rate     = rate; 
     185 vss->info.channels = channels; 
     186 vss->info.codec    = codec; 
     187 vss->info.bits     = bits; 
     188 
     189 ret = roar_vs_stream(vss, &(vss->info), dir, error); 
    172190 
    173191 if (ret == -1) { 
     
    225243 
    226244  _seterrre(); 
     245 } else { 
     246  vss->writec += ret; 
    227247 } 
    228248 
     
    244264 if ( ret == -1 ) { 
    245265  _seterrre(); 
     266 } else { 
     267  vss->readc += ret; 
    246268 } 
    247269 
     
    316338} 
    317339 
    318 ssize_t roar_vs_latency(roar_vs_t * vss, int backend, int * error) { 
     340static int _roar_vs_find_first_prim(roar_vs_t * vss) { 
     341 struct roar_stream stream; 
     342 struct roar_stream_info info; 
     343 int id[ROAR_STREAMS_MAX]; 
     344 int num; 
     345 int i; 
     346 
     347 if ( vss->first_primid != -1 ) 
     348  return vss->first_primid; 
     349 
     350 if ( vss->mixerid == -1 ) 
     351  return -1; 
     352 
     353 if ( (num = roar_list_streams(vss->con, id, ROAR_STREAMS_MAX)) == -1 ) { 
     354  return -1; 
     355 } 
     356 
     357 for (i = 0; i < num; i++) { 
     358  if ( roar_get_stream(vss->con, &stream, id[i]) == -1 ) 
     359   continue; 
     360 
     361  if ( stream.dir != ROAR_DIR_OUTPUT ) 
     362   continue; 
     363 
     364  if ( roar_stream_get_info(vss->con, &stream, &info) == -1 ) 
     365   continue; 
     366 
     367  if ( info.mixer == vss->mixerid ) { 
     368   vss->first_primid = id[i]; 
     369   return id[i]; 
     370  } 
     371 } 
     372 
     373 return -1; 
     374} 
     375 
     376ssize_t roar_vs_position(roar_vs_t * vss, int backend, int * error) { 
     377 struct roar_stream stream; 
     378 struct roar_stream      out_stream; 
     379 struct roar_stream_info out_info; 
     380 size_t offset; 
     381 
     382 if ( !(vss->flags & FLAG_STREAM) ) { 
     383  _seterr(ROAR_ERROR_INVAL); 
     384  return -1; 
     385 } 
     386 
     387 _initerr(); 
     388 
     389 if ( roar_get_stream(vss->con, &stream, roar_stream_get_id(&(vss->stream))) == -1 ) { 
     390  _seterrre(); 
     391  return -1; 
     392 } 
     393 
     394 switch (backend) { 
     395  case ROAR_VS_BACKEND_NONE: 
     396    return stream.pos; 
     397   break; 
     398  case ROAR_VS_BACKEND_FIRST: 
     399   // _roar_vs_find_first_prim(vss); 
     400    if ( vss->first_primid == -1 ) { 
     401     _seterr(ROAR_ERROR_UNKNOWN); 
     402     return -1; 
     403    } 
     404 
     405    roar_stream_new_by_id(&out_stream, vss->first_primid); 
     406 
     407    if ( roar_stream_get_info(vss->con, &out_stream, &out_info) == -1 ) { 
     408     _seterrre(); 
     409     return -1; 
     410    } 
     411 
     412    offset  = out_info.delay * vss->info.rate; 
     413    offset /= 1000000; 
     414 
     415    return stream.pos + offset; 
     416   break; 
     417  default: 
     418    _seterr(ROAR_ERROR_NOTSUP); 
     419    return -1; 
     420   break; 
     421 } 
     422 
    319423 _seterr(ROAR_ERROR_NOSYS); 
    320424 return -1; 
     425} 
     426 
     427roar_mus_t roar_vs_latency(roar_vs_t * vss, int backend, int * error) { 
     428 ssize_t pos  = roar_vs_position(vss, backend, error); 
     429 ssize_t bps;  // byte per sample 
     430 size_t  lioc; // local IO (byte) counter 
     431 size_t  lpos; // local possition 
     432 roar_mus_t  lag; 
     433 
     434 if (pos == -1) 
     435  return -1; 
     436 
     437 if ( !(vss->flags & FLAG_STREAM) ) { 
     438  _seterr(ROAR_ERROR_INVAL); 
     439  return -1; 
     440 } 
     441 
     442 if ( vss->writec == 0 ) { 
     443  lioc = vss->readc; 
     444 } else { 
     445  lioc = vss->writec; 
     446 } 
     447 
     448 _initerr(); 
     449 
     450 bps = roar_info2samplesize(&(vss->info)); 
     451 
     452 if ( bps == -1 ) { 
     453  _seterrre(); 
     454  return -1; 
     455 } 
     456 
     457 lpos = lioc / bps; 
     458 
     459 lag = (roar_mus_t)lpos - (roar_mus_t)pos; 
     460 
     461 // we now have the lag in frames 
     462 // return value are ms 
     463 // so we need to multiply with 1s/ms and 
     464 // multiply by 1/rate 
     465 
     466 lag *= 1000000; // 1s/ms 
     467 lag /= vss->info.rate; 
     468 
     469 return lag; 
    321470} 
    322471 
Note: See TracChangeset for help on using the changeset viewer.