mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-18 11:36:14 +02:00
Silence the PCM buffer if no chunk is available
This commit is contained in:
parent
147e4e9b7e
commit
168bc3f98b
7 changed files with 31 additions and 11 deletions
|
@ -108,7 +108,7 @@ void CoreAudioPlayer::playerCallback(AudioQueueRef queue, AudioQueueBufferRef bu
|
|||
/// TODO: sometimes this bufferedMS or AudioTimeStamp wraps around 1s (i.e. we're 1s out of sync (behind)) and recovers later on
|
||||
chronos::usec delay(bufferedMs * 1000);
|
||||
char* buffer = (char*)bufferRef->mAudioData;
|
||||
if (!pubStream_->getPlayerChunk(buffer, delay, frames_))
|
||||
if (!pubStream_->getPlayerChunkOrSilence(buffer, delay, frames_))
|
||||
{
|
||||
if (chronos::getTickCount() - lastChunkTick > 5000)
|
||||
{
|
||||
|
@ -117,7 +117,6 @@ void CoreAudioPlayer::playerCallback(AudioQueueRef queue, AudioQueueBufferRef bu
|
|||
return;
|
||||
}
|
||||
// LOG(INFO, LOG_TAG) << "Failed to get chunk. Playing silence.\n";
|
||||
memset(buffer, 0, buff_size_);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -85,20 +85,21 @@ void FilePlayer::requestAudio()
|
|||
if (buffer_.size() < needed)
|
||||
buffer_.resize(needed);
|
||||
|
||||
if (!stream_->getPlayerChunk(buffer_.data(), 10ms, numFrames))
|
||||
if (!stream_->getPlayerChunkOrSilence(buffer_.data(), 10ms, numFrames))
|
||||
{
|
||||
// LOG(INFO, LOG_TAG) << "Failed to get chunk. Playing silence.\n";
|
||||
memset(buffer_.data(), 0, needed);
|
||||
}
|
||||
else
|
||||
{
|
||||
adjustVolume(static_cast<char*>(buffer_.data()), numFrames);
|
||||
}
|
||||
|
||||
if (file_)
|
||||
{
|
||||
fwrite(buffer_.data(), 1, needed, file_.get());
|
||||
fflush(file_.get());
|
||||
}
|
||||
|
||||
loop();
|
||||
}
|
||||
|
||||
|
|
|
@ -152,10 +152,9 @@ oboe::DataCallbackResult OboePlayer::onAudioReady(oboe::AudioStream* /*oboeStrea
|
|||
// LOG(INFO, LOG_TAG) << "getCurrentOutputLatencyMillis: " << output_latency << ", frames: " << numFrames << "\n";
|
||||
chronos::usec delay(static_cast<int>(output_latency * 1000.));
|
||||
|
||||
if (!stream_->getPlayerChunk(audioData, delay, numFrames))
|
||||
if (!stream_->getPlayerChunkOrSilence(audioData, delay, numFrames))
|
||||
{
|
||||
// LOG(INFO, LOG_TAG) << "Failed to get chunk. Playing silence.\n";
|
||||
memset(audioData, 0, numFrames * stream_->getFormat().frameSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -78,10 +78,9 @@ void OpenslPlayer::playerCallback(SLAndroidSimpleBufferQueueItf bq)
|
|||
return;
|
||||
|
||||
chronos::usec delay(ms_ * 1000);
|
||||
if (!pubStream_->getPlayerChunk(buffer[curBuffer], delay, frames_))
|
||||
if (!pubStream_->getPlayerChunkOrSilence(buffer[curBuffer], delay, frames_))
|
||||
{
|
||||
// LOG(INFO, LOG_TAG) << "Failed to get chunk. Playing silence.\n";
|
||||
memset(buffer[curBuffer], 0, buff_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -299,10 +299,9 @@ void PulsePlayer::writeCallback(pa_stream* stream, size_t nbytes)
|
|||
if (buffer_.size() < nbytes)
|
||||
buffer_.resize(nbytes);
|
||||
// LOG(TRACE, LOG_TAG) << "writeCallback latency " << usec << " us, frames: " << numFrames << "\n";
|
||||
if (!stream_->getPlayerChunk(buffer_.data(), std::chrono::microseconds(usec), numFrames))
|
||||
if (!stream_->getPlayerChunkOrSilence(buffer_.data(), std::chrono::microseconds(usec), numFrames))
|
||||
{
|
||||
// LOG(INFO, LOG_TAG) << "Failed to get chunk. Playing silence.\n";
|
||||
memset(buffer_.data(), 0, buffer_.size());
|
||||
// LOG(TRACE, LOG_TAG) << "Failed to get chunk. Playing silence.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "common/aixlog.hpp"
|
||||
#include "common/snap_exception.hpp"
|
||||
#include "common/str_compat.hpp"
|
||||
#include "common/utils/logging.hpp"
|
||||
#include "time_provider.hpp"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
@ -441,3 +442,16 @@ bool Stream::getPlayerChunk(void* outputBuffer, const cs::usec& outputBufferDacT
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Stream::getPlayerChunkOrSilence(void* outputBuffer, const chronos::usec& outputBufferDacTime, uint32_t frames)
|
||||
{
|
||||
bool result = getPlayerChunk(outputBuffer, outputBufferDacTime, frames);
|
||||
if (!result)
|
||||
{
|
||||
static utils::logging::TimeConditional cond(1s);
|
||||
LOG(DEBUG, LOG_TAG) << cond << "Failed to get chunk, returning silence\n";
|
||||
getSilentPlayerChunk(outputBuffer, frames);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -48,8 +48,17 @@ public:
|
|||
|
||||
/// Get PCM data, which will be played out in "outputBufferDacTime" time
|
||||
/// frame = (num_channels) * (1 sample in bytes) = (2 channels) * (2 bytes (16 bits) per sample) = 4 bytes (32 bits)
|
||||
/// @param[out] outputBuffer the buffer to be filled with PCM data
|
||||
/// @param outputBufferDacTime the duration until the PCM chunk will be audible
|
||||
/// @param frames the number of requested frames to be copied into outputBuffer
|
||||
/// @return true if a chunk was available and successfully copied to outputBuffer
|
||||
bool getPlayerChunk(void* outputBuffer, const chronos::usec& outputBufferDacTime, uint32_t frames);
|
||||
|
||||
/// Try to get a player chunk and fill the buffer with silence if it fails
|
||||
/// @sa getPlayerChunk
|
||||
/// @return true if a chunk was available and successfully copied to outputBuffer, else false and outputBuffer is filled with silence
|
||||
bool getPlayerChunkOrSilence(void* outputBuffer, const chronos::usec& outputBufferDacTime, uint32_t frames);
|
||||
|
||||
/// "Server buffer": playout latency, e.g. 1000ms
|
||||
void setBufferLen(size_t bufferLenMs);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue