void Mixer::renderSamples() { /* extract buffer info now that the SID is updated. * clock() may update bufferpos. * NB: if chip2 exists, its bufferpos is identical to chip1's. */ const int sampleCount = m_chips.front()->bufferpos(); const unsigned int channels = m_stereo ? 2 : 1; short *buf = m_sampleBuffer + m_sampleIndex; int i = 0; while (i < sampleCount && m_sampleIndex < m_sampleCount) { const int dither = triangularDithering(); for (size_t k = 0; k < m_buffers.size(); k++) { m_iSamples[k] = (int_least32_t(m_buffers[k][i]) * m_volume[k] + dither) / VOLUME_MAX; } for (unsigned int k = 0; k < channels; k++) { *buf++ = (m_mix[k])(&m_iSamples.front()); m_sampleIndex++; } ++i; } /* move the unhandled data to start of buffer, if any. */ const int samplesLeft = sampleCount - i; std::for_each(m_buffers.begin(), m_buffers.end(), bufferMove(i, samplesLeft)); std::for_each(m_chips.begin(), m_chips.end(), bufferPos(samplesLeft)); }
void Mixer::doMix() { short *buf = m_sampleBuffer + m_sampleIndex; // extract buffer info now that the SID is updated. // clock() may update bufferpos. // NB: if more than one chip exists, their bufferpos is identical to first chip's. const int sampleCount = m_chips.front()->bufferpos(); int i = 0; while (i < sampleCount) { // Handle whatever output the sid has generated so far if (m_sampleIndex >= m_sampleCount) { break; } // Are there enough samples to generate the next one? if (i + m_fastForwardFactor >= sampleCount) { break; } // This is a crude boxcar low-pass filter to // reduce aliasing during fast forward. for (size_t k = 0; k < m_buffers.size(); k++) { int_least32_t sample = 0; const short *buffer = m_buffers[k] + i; for (int j = 0; j < m_fastForwardFactor; j++) { sample += buffer[j]; } m_iSamples[k] = sample / m_fastForwardFactor; } // increment i to mark we ate some samples, finish the boxcar thing. i += m_fastForwardFactor; const int dither = triangularDithering(); const unsigned int channels = m_stereo ? 2 : 1; for (unsigned int ch = 0; ch < channels; ch++) { const int_least32_t tmp = ((this->*(m_mix[ch]))() * m_volume[ch] + dither) / VOLUME_MAX; assert(tmp >= -32768 && tmp <= 32767); *buf++ = static_cast<short>(tmp); m_sampleIndex++; } } // move the unhandled data to start of buffer, if any. const int samplesLeft = sampleCount - i; std::for_each(m_buffers.begin(), m_buffers.end(), bufferMove(i, samplesLeft)); std::for_each(m_chips.begin(), m_chips.end(), bufferPos(samplesLeft)); }
void Mixer::doMix() { short *buf = m_sampleBuffer + m_sampleIndex; /* extract buffer info now that the SID is updated. * clock() may update bufferpos. * NB: if chip2 exists, its bufferpos is identical to chip1's. */ const int sampleCount = m_chips[0]->bufferpos(); int i = 0; while (i < sampleCount) { /* Handle whatever output the sid has generated so far */ if (m_sampleIndex >= m_sampleCount) { break; } /* Are there enough samples to generate the next one? */ if (i + m_fastForwardFactor >= sampleCount) { break; } const int dither = triangularDithering(); /* This is a crude boxcar low-pass filter to * reduce aliasing during fast forward. */ for (size_t k = 0; k < m_buffers.size(); k++) { int_least32_t sample = 0; const short *buffer = m_buffers[k] + i; for (int j = 0; j < m_fastForwardFactor; j++) { sample += buffer[j]; } m_iSamples[k] = (sample * m_volume[k] + dither) / VOLUME_MAX; m_iSamples[k] /= m_fastForwardFactor; } /* increment i to mark we ate some samples, finish the boxcar thing. */ i += m_fastForwardFactor; const unsigned int channels = m_stereo ? 2 : 1; for (unsigned int k = 0; k < channels; k++) { *buf++ = (this->*(m_mix[k]))(); m_sampleIndex++; } } /* move the unhandled data to start of buffer, if any. */ const int samplesLeft = sampleCount - i; std::for_each(m_buffers.begin(), m_buffers.end(), bufferMove(i, samplesLeft)); std::for_each(m_chips.begin(), m_chips.end(), bufferPos(samplesLeft - 1)); }