Codebase list squeezelite / 3c426f9
support output device on/off with portaudio, default to playnice on osx Adrian Smith 10 years ago
1 changed file(s) with 37 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
466466 bool probe_thread_running = false;
467467
468468 static void *pa_probe() {
469 // this is a hack to partially support hot plugging of devices
470 // we rely on terminating and reinitalising PA to get an updated list of devices and use name for output.device
469 bool output_off;
470 LOCK;
471 output_off = (output.state == OUTPUT_OFF);
472 UNLOCK;
473
471474 while (probe_thread_running) {
472 LOG_INFO("probing device %s", output.device);
473475 LOCK;
474 Pa_Terminate();
475 Pa_Initialize();
476 pa.stream = NULL;
477 if (pa_device_id(output.device) != -1) {
478 LOG_INFO("found");
479 probe_thread_running = false;
480 _pa_open();
476 if (output_off) {
477 if (output.state != OUTPUT_OFF) {
478 LOG_INFO("output on");
479 probe_thread_running = false;
480 pa.stream = NULL;
481 _pa_open();
482 }
481483 } else {
482 sleep(5);
484 // this is a hack to partially support hot plugging of devices
485 // we rely on terminating and reinitalising PA to get an updated list of devices and use name for output.device
486 LOG_INFO("probing device %s", output.device);
487 Pa_Terminate();
488 Pa_Initialize();
489 pa.stream = NULL;
490 if (pa_device_id(output.device) != -1) {
491 LOG_INFO("device reopen");
492 probe_thread_running = false;
493 _pa_open();
494 }
483495 }
484496 UNLOCK;
497
498 if (probe_thread_running) {
499 sleep(output_off ? 1 : 5);
500 }
485501 }
486502
487503 return 0;
513529 #if OSX
514530 // enable pro mode which aims to avoid resampling if possible
515531 // see http://code.google.com/p/squeezelite/issues/detail?id=11 & http://code.google.com/p/squeezelite/issues/detail?id=37
516 // command line controls osx_playnice which is -1 if not specified, 0 or 1
532 // command line controls osx_playnice which is -1 if not specified, 0 or 1 - choose playnice if -1 or 1
517533 PaMacCoreStreamInfo macInfo;
518534 unsigned long streamInfoFlags;
519 if (output.osx_playnice == 1 ||
520 (output.osx_playnice == -1 && !strcmp(Pa_GetDeviceInfo(outputParameters.device)->name, "Built-in Output"))) {
535 if (output.osx_playnice) {
521536 LOG_INFO("opening device in PlayNice mode");
522537 streamInfoFlags = paMacCorePlayNice;
523538 } else {
529544 #endif
530545 }
531546
532 if (!err &&
547 if (!err && output.state != OUTPUT_OFF &&
533548 (err = Pa_OpenStream(&pa.stream, NULL, &outputParameters, (double)output.current_sample_rate, paFramesPerBufferUnspecified,
534549 paPrimeOutputBuffersUsingStreamCallback | paDitherOff, pa_callback, NULL)) != paNoError) {
535550 LOG_WARN("error opening device %i - %s : %s", outputParameters.device, Pa_GetDeviceInfo(outputParameters.device)->name,
536551 Pa_GetErrorText(err));
537552 }
538553
539 if (!err) {
554 if (!err && output.state != OUTPUT_OFF) {
540555 LOG_INFO("opened device %i - %s at %u latency %u ms", outputParameters.device, Pa_GetDeviceInfo(outputParameters.device)->name,
541556 (unsigned int)Pa_GetStreamInfo(pa.stream)->sampleRate, (unsigned int)(Pa_GetStreamInfo(pa.stream)->outputLatency * 1000));
542557
551566 }
552567 }
553568
554 if (err && !probe_thread_running) {
569 if ((err || output.state == OUTPUT_OFF) && !probe_thread_running) {
555570 // create a thread to probe for the device
556571 #if LINUX || OSX
557572 pthread_create(&probe_thread, NULL, pa_probe, NULL);
12521267 memset(optr, 0, (pa_frames_wanted - frames) * BYTES_PER_FRAME);
12531268 }
12541269
1255 if (pa.rate != output.current_sample_rate) {
1270 if (output.state == OUTPUT_OFF) {
1271 LOG_INFO("output off");
1272 UNLOCK;
1273 return paComplete;
1274 } else if (pa.rate != output.current_sample_rate) {
12561275 UNLOCK;
12571276 return paComplete;
12581277 } else {