| 549 | } |
| 550 | |
| 551 | void InputStream::enqueueSamples( pa_stream *s, size_t nbytes ) |
| 552 | { |
| 553 | CI_ASSERT( nbytes % mBytesPerFrame == 0 ); |
| 554 | |
| 555 | // TODO: use the result of pa_stream_readable_size here? |
| 556 | // - can use it to check if there is enough room in the ringbuffer left to write to |
| 557 | while( pa_stream_readable_size( s ) > 0 ) { |
| 558 | const void *data; |
| 559 | |
| 560 | if( pa_stream_peek( s, &data, &nbytes ) < 0 ) { |
| 561 | auto errorStr = pa_strerror( pa_context_errno( mContext->mPaContext ) ); |
| 562 | CI_LOG_E( "pa_stream_peek() failed: " << errorStr ); |
| 563 | CI_ASSERT_NOT_REACHABLE(); |
| 564 | return; |
| 565 | } |
| 566 | |
| 567 | CI_ASSERT( nbytes > 0 ); |
| 568 | |
| 569 | const size_t numFramesRead = nbytes / mBytesPerFrame; |
| 570 | |
| 571 | // resize mReadBuffer if necessary |
| 572 | mReadBuffer.setSize( numFramesRead, mNumChannels ); |
| 573 | |
| 574 | if( data ) { |
| 575 | // de-interleave and write data to a ringbuffer that will be consumed in InpudeDeviceNode's process method |
| 576 | ci::audio::dsp::deinterleave( (const float *)data, mReadBuffer.getData(), numFramesRead, mNumChannels, numFramesRead ); |
| 577 | } |
| 578 | else { |
| 579 | // there is a hole in the stream, generate silence |
| 580 | mReadBuffer.zero(); |
| 581 | } |
| 582 | |
| 583 | size_t framesBuffered = 0; |
| 584 | for( size_t ch = 0; ch < mRingBuffers.size(); ch++ ) { |
| 585 | if( mRingBuffers[ch].write( mReadBuffer.getChannel( ch ), numFramesRead ) ) { |
| 586 | // only set this to non-zero if we succeeded at writing to the ringbuffer |
| 587 | framesBuffered = numFramesRead; |
| 588 | } |
| 589 | else { |
| 590 | //CI_LOG_W( "RingBuffer full for channel: " << ch ); |
| 591 | if( mMarkOverrunFn ) |
| 592 | mMarkOverrunFn(); |
| 593 | } |
| 594 | } |
| 595 | |
| 596 | mNumFramesBuffered += framesBuffered; |
| 597 | pa_stream_drop( s ); |
| 598 | } |
| 599 | |
| 600 | } |
| 601 | |
| 602 | } // namespace pulse |
| 603 |
no test coverage detected