Changeset 4206:76162667542c in roaraudio for libroar/vs.c
- Timestamp:
- 08/19/10 22:37:56 (14 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libroar/vs.c
r4199 r4206 39 39 #define FLAG_STREAM 0x0001 40 40 #define FLAG_NONBLOCK 0x0002 41 #define FLAG_BUFFERED 0x0004 41 42 42 43 #define _initerr() do { errno = 0; roar_err_clear(); } while(0) … … 51 52 struct roar_stream stream; 52 53 struct roar_vio_calls vio; 54 struct roar_audio_info info; 55 size_t readc, writec; 56 int mixerid; 57 int first_primid; 53 58 }; 59 60 static int _roar_vs_find_first_prim(roar_vs_t * vss); 54 61 55 62 const char * roar_vs_strerr(int error) { … … 93 100 memset(vss, 0, sizeof(roar_vs_t)); 94 101 102 vss->mixerid = -1; 103 vss->first_primid = -1; 104 95 105 return vss; 96 106 } … … 130 140 131 141 int roar_vs_stream(roar_vs_t * vss, const struct roar_audio_info * info, int dir, int * error) { 142 struct roar_stream_info sinfo; 132 143 int ret; 133 144 … … 138 149 139 150 _initerr(); 151 152 if ( info != &(vss->info) ) 153 memcpy(&(vss->info), info, sizeof(struct roar_audio_info)); 140 154 141 155 ret = roar_vio_simple_new_stream_obj(&(vss->vio), vss->con, &(vss->stream), … … 149 163 } 150 164 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 151 170 vss->flags |= FLAG_STREAM; 152 171 … … 156 175 roar_vs_t * roar_vs_new_simple(const char * server, const char * name, int rate, int channels, int codec, int bits, int dir, int * error) { 157 176 roar_vs_t * vss = roar_vs_new(server, name, error); 158 struct roar_audio_info info;159 177 int ret; 160 178 … … 162 180 return NULL; 163 181 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); 172 190 173 191 if (ret == -1) { … … 225 243 226 244 _seterrre(); 245 } else { 246 vss->writec += ret; 227 247 } 228 248 … … 244 264 if ( ret == -1 ) { 245 265 _seterrre(); 266 } else { 267 vss->readc += ret; 246 268 } 247 269 … … 316 338 } 317 339 318 ssize_t roar_vs_latency(roar_vs_t * vss, int backend, int * error) { 340 static 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 376 ssize_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 319 423 _seterr(ROAR_ERROR_NOSYS); 320 424 return -1; 425 } 426 427 roar_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; 321 470 } 322 471
Note: See TracChangeset
for help on using the changeset viewer.