- if (!numbytes && *wng->loaded >= sizeof(short))
- goto min_delay; /* there's a buffer to fill */
- if (!numbytes)
- return 1;
- divisor = powd->samplerate * powd->channels * 2 / numbytes;
- if (divisor)
- tv_divide(divisor, &tmp, &delay);
- if (tv_diff(&s->timeout, &delay, NULL) > 0)
- s->timeout = delay;
-// PARA_DEBUG_LOG("delay: %lu:%lu\n", (long unsigned) s->timeout.tv_sec,
-// (long unsigned) s->timeout.tv_usec);
- return 1;
-min_delay:
- PARA_DEBUG_LOG("%s\n", "minimal delay");
- s->timeout.tv_sec = 0;
- s->timeout.tv_usec = 1;
- return 1;
+ if (!powd) {
+ ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF);
+ if (ret == 0)
+ return;
+ if (ret < 0)
+ goto remove_btrn;
+ ret = core_audio_init(wn);
+ if (ret < 0)
+ goto remove_btrn;
+ powd = wn->private_data;
+ ret = -E_UNIT_START;
+ if (AudioOutputUnitStart(powd->audio_unit) != noErr) {
+ AudioUnitUninitialize(powd->audio_unit);
+ CloseComponent(powd->audio_unit);
+ btr_remove_node(&powd->callback_btrn);
+ goto remove_btrn;
+ }
+ }
+ mutex_lock(powd->mutex);
+ ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_INTERNAL);
+ if (ret > 0)
+ btr_pushdown(btrn);
+ if (ret < 0 && need_drain_delay(powd))
+ ret = 0;
+ if (ret >= 0) {
+ mutex_unlock(powd->mutex);
+ return;
+ }
+ AudioOutputUnitStop(powd->audio_unit);
+ AudioUnitUninitialize(powd->audio_unit);
+ CloseComponent(powd->audio_unit);
+ btr_remove_node(&powd->callback_btrn);
+ mutex_unlock(powd->mutex);
+remove_btrn:
+ btr_remove_node(&wn->btrn);
+ PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
+ t->error = ret;