comparison libao2/ao_nas.c @ 12022:293141b57c01

Use MultiplyElement to control volume. Works with multiple videos at the same time and even when NAS does not control the mixer or it is unavailable. Show buffer underrun hint only once and add missing linebreaks.
author ranma
date Sat, 13 Mar 2004 21:54:35 +0000
parents 12b1790038b0
children 99798c3cdb93
comparison
equal deleted inserted replaced
12021:cd33d1e3b709 12022:293141b57c01
107 107
108 struct ao_nas_data { 108 struct ao_nas_data {
109 AuServer *aud; 109 AuServer *aud;
110 AuFlowID flow; 110 AuFlowID flow;
111 AuDeviceID dev; 111 AuDeviceID dev;
112 AuFixedPoint gain;
112 113
113 unsigned int state; 114 unsigned int state;
114 int expect_underrun; 115 int expect_underrun;
115 116
116 void *client_buffer; 117 void *client_buffer;
264 // buffer underrun -> refill buffer 265 // buffer underrun -> refill buffer
265 nas_data->server_buffer_used = 0; 266 nas_data->server_buffer_used = 0;
266 if (nas_data->expect_underrun) { 267 if (nas_data->expect_underrun) {
267 nas_data->expect_underrun = 0; 268 nas_data->expect_underrun = 0;
268 } else { 269 } else {
270 static int hint = 1;
269 mp_msg(MSGT_AO, MSGL_WARN, 271 mp_msg(MSGT_AO, MSGL_WARN,
270 "ao_nas: Buffer underrun.\n"); 272 "ao_nas: Buffer underrun.\n");
271 mp_msg(MSGT_AO, MSGL_HINT, 273 if (hint) {
272 "Possible reasons are:" 274 hint = 0;
273 "1) Network congestion." 275 mp_msg(MSGT_AO, MSGL_HINT,
274 "2) Your NAS server is too slow." 276 "Possible reasons are:\n"
275 "Try renicing your nasd to e.g. -15.\n"); 277 "1) Network congestion.\n"
278 "2) Your NAS server is too slow.\n"
279 "Try renicing your nasd to e.g. -15.\n");
280 }
276 } 281 }
277 if (nas_readBuffer(nas_data, 282 if (nas_readBuffer(nas_data,
278 nas_data->server_buffer_size - 283 nas_data->server_buffer_size -
279 nas_data->server_buffer_used) != 0) { 284 nas_data->server_buffer_used) != 0) {
280 event->cur_state = AuStateStart; 285 event->cur_state = AuStateStart;
313 return AuFormatLinearSigned8; 318 return AuFormatLinearSigned8;
314 case AFMT_U16_LE: 319 case AFMT_U16_LE:
315 return AuFormatLinearUnsigned16LSB; 320 return AuFormatLinearUnsigned16LSB;
316 case AFMT_U16_BE: 321 case AFMT_U16_BE:
317 return AuFormatLinearUnsigned16MSB; 322 return AuFormatLinearUnsigned16MSB;
318 #ifndef WORDS_BIGENDIAN
319 default:
320 *format=AFMT_S16_LE;
321 #endif
322 case AFMT_S16_LE: 323 case AFMT_S16_LE:
323 return AuFormatLinearSigned16LSB; 324 return AuFormatLinearSigned16LSB;
324 #ifdef WORDS_BIGENDIAN
325 default:
326 *format=AFMT_S16_BE;
327 #endif
328 case AFMT_S16_BE: 325 case AFMT_S16_BE:
329 return AuFormatLinearSigned16MSB; 326 return AuFormatLinearSigned16MSB;
330 case AFMT_MU_LAW: 327 case AFMT_MU_LAW:
331 return AuFormatULAW8; 328 return AuFormatULAW8;
329 default:
330 *format=AFMT_S16_NE;
331 return nas_aformat_to_auformat(format);
332 } 332 }
333 } 333 }
334 334
335 // to set/get/query special features/parameters 335 // to set/get/query special features/parameters
336 static int control(int cmd, void *arg) 336 static int control(int cmd, void *arg)
337 { 337 {
338 AuDeviceAttributes *dattr; 338 AuElementParameters aep;
339 AuFixedPoint fpgain; 339 AuStatus as;
340 AuStatus as;
341 int gain;
342 int retval = CONTROL_UNKNOWN; 340 int retval = CONTROL_UNKNOWN;
343 341
344 ao_control_vol_t *vol = (ao_control_vol_t *)arg; 342 ao_control_vol_t *vol = (ao_control_vol_t *)arg;
345
346 dattr = AuGetDeviceAttributes(nas_data->aud, nas_data->dev, &as);
347 if (as != AuSuccess) {
348 nas_print_error(nas_data->aud,
349 "control(): AuGetDeviceAttributes", as);
350 return CONTROL_ERROR;
351 }
352 gain = AuFixedPointRoundDown(AuDeviceGain(dattr));
353 // kn: 0 <= gain <= 100
354 343
355 switch (cmd) { 344 switch (cmd) {
356 case AOCONTROL_GET_VOLUME: 345 case AOCONTROL_GET_VOLUME:
357 346
358 vol->right = (float) gain; 347 vol->right = (float)nas_data->gain/AU_FIXED_POINT_SCALE*50;
359 vol->left = vol->right; 348 vol->left = vol->right;
360 349
361 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: AOCONTROL_GET_VOLUME: %d\n", gain); 350 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: AOCONTROL_GET_VOLUME: %08x\n", nas_data->gain);
362 retval = CONTROL_OK; 351 retval = CONTROL_OK;
363 break; 352 break;
364 353
365 case AOCONTROL_SET_VOLUME: 354 case AOCONTROL_SET_VOLUME:
366 /* 355 /*
367 * kn: we should have vol->left == vol->right but i don't 356 * kn: we should have vol->left == vol->right but i don't
368 * know if something can change it outside of ao_nas 357 * know if something can change it outside of ao_nas
369 * so i take the mean of both values. 358 * so i take the mean of both values.
370 */ 359 */
371 gain = (int) ((vol->left+vol->right)/2); 360 nas_data->gain = AU_FIXED_POINT_SCALE*((vol->left+vol->right)/2)/50;
372 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: AOCONTROL_SET_VOLUME: %d\n", gain); 361 mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: AOCONTROL_SET_VOLUME: %08x\n", nas_data->gain);
373 362
374 fpgain = AuFixedPointFromSum(gain, 0); 363 aep.parameters[AuParmsMultiplyConstantConstant]=nas_data->gain;
375 AuDeviceGain(dattr) = fpgain; 364 aep.flow = nas_data->flow;
376 AuSetDeviceAttributes(nas_data->aud, nas_data->dev, 365 aep.element_num = 1;
377 AuCompDeviceGainMask, dattr, &as); 366 aep.num_parameters = AuParmsMultiplyConstant;
367
368 AuSetElementParameters(nas_data->aud, 1, &aep, &as);
378 if (as != AuSuccess) { 369 if (as != AuSuccess) {
379 nas_print_error(nas_data->aud, 370 nas_print_error(nas_data->aud,
380 "control(): AuSetDeviceAttributes", as); 371 "control(): AuSetElementParameters", as);
381 retval = CONTROL_ERROR; 372 retval = CONTROL_ERROR;
382 } else retval = CONTROL_OK; 373 } else retval = CONTROL_OK;
383 break; 374 break;
384 }; 375 };
385 376
386 AuFreeDeviceAttributes(nas_data->aud, 1, dattr);
387 return retval; 377 return retval;
388 } 378 }
389 379
390 // open & setup audio device 380 // open & setup audio device
391 // return: 1=success 0=fail 381 // return: 1=success 0=fail
458 448
459 AuMakeElementImportClient(elms, rate, auformat, channels, AuTrue, 449 AuMakeElementImportClient(elms, rate, auformat, channels, AuTrue,
460 buffer_size / bytes_per_sample, 450 buffer_size / bytes_per_sample,
461 (buffer_size - NAS_FRAG_SIZE) / 451 (buffer_size - NAS_FRAG_SIZE) /
462 bytes_per_sample, 0, NULL); 452 bytes_per_sample, 0, NULL);
463 AuMakeElementExportDevice(elms+1, 0, nas_data->dev, rate, 453 nas_data->gain = AuFixedPointFromFraction(1, 1);
454 AuMakeElementMultiplyConstant(elms+1, 0, nas_data->gain);
455 AuMakeElementExportDevice(elms+2, 1, nas_data->dev, rate,
464 AuUnlimitedSamples, 0, NULL); 456 AuUnlimitedSamples, 0, NULL);
465 AuSetElements(nas_data->aud, nas_data->flow, AuTrue, 2, elms, &as); 457 AuSetElements(nas_data->aud, nas_data->flow, AuTrue, sizeof(elms)/sizeof(*elms), elms, &as);
466 if (as != AuSuccess) { 458 if (as != AuSuccess) {
467 nas_print_error(nas_data->aud, "init(): AuSetElements", as); 459 nas_print_error(nas_data->aud, "init(): AuSetElements", as);
468 AuCloseServer(nas_data->aud); 460 AuCloseServer(nas_data->aud);
469 nas_data->aud = 0; 461 nas_data->aud = 0;
470 return 0; 462 return 0;