void EngineNetworkStream::write(const CSAMPLE* buffer, int frames) { if (m_pWorker.isNull()) { return; } //qDebug() << "EngineNetworkStream::write()" << frames; if (!m_pWorker->threadWaiting()) { // no thread waiting, so we can advance the stream without // buffering m_streamFramesWritten += frames; return; } int writeAvailable = m_pOutputFifo->writeAvailable(); int writeRequired = frames * m_numOutputChannels; if (writeAvailable < writeRequired) { qDebug() << "EngineNetworkStream::write() buffer full, loosing samples"; NetworkStreamWorker::debugState(); m_writeOverflowCount++; } int copyCount = math_min(writeAvailable, writeRequired); if (copyCount > 0) { (void)m_pOutputFifo->write(buffer, copyCount); // we advance the frame only by the samples we have actually copied // This means in case of buffer full (where we loose some frames) // we do not get out of sync, and the syncing code tries to catch up the // stream by writing silence, once the buffer is free. m_streamFramesWritten += copyCount / m_numOutputChannels; } scheduleWorker(); }
static void OSThreadProcAttr workerStart(Task *task) { Capability *cap; // See startWorkerTask(). ACQUIRE_LOCK(&task->lock); cap = task->cap; RELEASE_LOCK(&task->lock); if (RtsFlags.ParFlags.setAffinity) { setThreadAffinity(cap->no, n_capabilities); } // set the thread-local pointer to the Task: setMyTask(task); newInCall(task); scheduleWorker(cap,task); }
void EngineNetworkStream::writeSilence(int frames) { if (m_pWorker.isNull()) { return; } //qDebug() << "EngineNetworkStream::writeSilence()" << frames; if (!m_pWorker->threadWaiting()) { // no thread waiting, so we can advance the stream without // buffering m_streamFramesWritten += frames; return; } int writeAvailable = m_pOutputFifo->writeAvailable(); int writeRequired = frames * m_numOutputChannels; if (writeAvailable < writeRequired) { qDebug() << "EngineNetworkStream::writeSilence() buffer full"; NetworkStreamWorker::debugState(); } int clearCount = math_min(writeAvailable, writeRequired); if (clearCount > 0) { CSAMPLE* dataPtr1; ring_buffer_size_t size1; CSAMPLE* dataPtr2; ring_buffer_size_t size2; (void)m_pOutputFifo->aquireWriteRegions(clearCount, &dataPtr1, &size1, &dataPtr2, &size2); SampleUtil::clear(dataPtr1,size1); if (size2 > 0) { SampleUtil::clear(dataPtr2,size2); } m_pOutputFifo->releaseWriteRegions(clearCount); // we advance the frame only by the samples we have actually cleared m_streamFramesWritten += clearCount / m_numOutputChannels; } scheduleWorker(); }
static void OSThreadProcAttr workerStart(Task *task) { Capability *cap; // See startWorkerTask(). ACQUIRE_LOCK(&task->lock); cap = task->cap; RELEASE_LOCK(&task->lock); if (RtsFlags.ParFlags.setAffinity) { setThreadAffinity(cap->no, n_capabilities); } // set the thread-local pointer to the Task: setMyTask(task); newInCall(task); // Everything set up; emit the event before the worker starts working. traceTaskCreate(task, cap); scheduleWorker(cap,task); }