| 532 | } |
| 533 | |
| 534 | void |
| 535 | AudioPlayback::write(const SUCOMPLEX *samples, SUSCOUNT size) |
| 536 | { |
| 537 | unsigned int bufferSize = this->bufferSize; |
| 538 | |
| 539 | while (size > 0 && this->running && this->ready) { |
| 540 | SUSCOUNT chunk = size; |
| 541 | SUSCOUNT remaining; |
| 542 | float *start; |
| 543 | |
| 544 | // No current buffer, try to allocate |
| 545 | if (this->current_buffer == nullptr) { |
| 546 | this->ptr = 0; |
| 547 | if ((this->current_buffer = this->bufferList.reserve()) == nullptr) { |
| 548 | // Somehow the playback thread is slow... |
| 549 | return; |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | start = this->current_buffer + this->ptr; |
| 554 | |
| 555 | if (chunk > bufferSize - this->ptr) |
| 556 | chunk = bufferSize - this->ptr; |
| 557 | remaining = chunk; |
| 558 | |
| 559 | while (remaining-- > 0) |
| 560 | *start++ = SU_C_REAL(*samples++); |
| 561 | |
| 562 | this->ptr += chunk; |
| 563 | size -= chunk; |
| 564 | |
| 565 | // Buffer full, send to playback thread. |
| 566 | if (this->ptr == bufferSize) { |
| 567 | this->current_buffer = nullptr; |
| 568 | this->bufferList.commit(); |
| 569 | |
| 570 | // If buffering, we wait until we have SIGDIGGER_AUDIO_BUFFER_MIN |
| 571 | // buffers full. When that happens, we restart the thread. |
| 572 | if (this->buffering) { |
| 573 | if (++this->completed == SIGDIGGER_AUDIO_BUFFER_MIN) { |
| 574 | emit restart(); |
| 575 | this->buffering = false; |
| 576 | } |
| 577 | } |
| 578 | } |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | void |
| 583 | AudioPlayback::onReady(void) |