MCPcopy Create free account
hub / github.com/OneLoneCoder/olcPixelGameEngine / AudioThread

Method AudioThread

extensions/olcPGEX_Sound.h:520–587  ·  view source on GitHub ↗

Audio thread. This loop responds to requests from the soundcard to fill 'blocks' with audio data. If no requests are available it goes dormant until the sound card is ready for more data. The block is fille by the "user" in some manner and then issued to the soundcard.

Source from the content-addressed store, hash-verified

518 // card is ready for more data. The block is fille by the "user" in some manner
519 // and then issued to the soundcard.
520 void SOUND::AudioThread()
521 {
522 m_fGlobalTime = 0.0f;
523 static float fTimeStep = 1.0f / (float)m_nSampleRate;
524
525 // Goofy hack to get maximum integer for a type at run-time
526 short nMaxSample = (short)pow(2, (sizeof(short) * 8) - 1) - 1;
527 float fMaxSample = (float)nMaxSample;
528 short nPreviousSample = 0;
529
530 auto tp1 = std::chrono::system_clock::now();
531 auto tp2 = std::chrono::system_clock::now();
532
533 while (m_bAudioThreadActive)
534 {
535 // Wait for block to become available
536 if (m_nBlockFree == 0)
537 {
538 std::unique_lock<std::mutex> lm(m_muxBlockNotZero);
539 while (m_nBlockFree == 0) // sometimes, Windows signals incorrectly
540 m_cvBlockNotZero.wait(lm);
541 }
542
543 // Block is here, so use it
544 m_nBlockFree--;
545
546 // Prepare block for processing
547 if (m_pWaveHeaders[m_nBlockCurrent].dwFlags & WHDR_PREPARED)
548 waveOutUnprepareHeader(m_hwDevice, &m_pWaveHeaders[m_nBlockCurrent], sizeof(WAVEHDR));
549
550 short nNewSample = 0;
551 int nCurrentBlock = m_nBlockCurrent * m_nBlockSamples;
552
553 auto clip = [](float fSample, float fMax)
554 {
555 if (fSample >= 0.0)
556 return fmin(fSample, fMax);
557 else
558 return fmax(fSample, -fMax);
559 };
560
561 tp2 = std::chrono::system_clock::now();
562 std::chrono::duration<float> elapsedTime = tp2 - tp1;
563 tp1 = tp2;
564
565 // Our time per frame coefficient
566 float fElapsedTime = elapsedTime.count();
567
568 for (unsigned int n = 0; n < m_nBlockSamples; n += m_nChannels)
569 {
570 // User Process
571 for (unsigned int c = 0; c < m_nChannels; c++)
572 {
573 nNewSample = (short)(clip(GetMixerOutput(c, m_fGlobalTime + fTimeStep * (float)n, fTimeStep), 1.0) * fMaxSample);
574 m_pBlockMemory[nCurrentBlock + n + c] = nNewSample;
575 nPreviousSample = nNewSample;
576 }
577 }

Callers

nothing calls this directly

Calls 4

waitMethod · 0.80
countMethod · 0.80
emptyMethod · 0.80
resizeMethod · 0.45

Tested by

no test coverage detected