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)); }
void Mixer::renderSilence() { std::for_each(m_chips.begin(), m_chips.end(), clockChipSilent); const int sampleCount = m_chips.front()->bufferpos(); const unsigned int channels = m_stereo ? 2 : 1; const int i = std::min<int>(sampleCount, (m_sampleCount - m_sampleIndex) / channels); m_sampleIndex += channels * i; const int samplesLeft = sampleCount - i; std::for_each(m_chips.begin(), m_chips.end(), bufferPos(samplesLeft)); }
void IndexPage::loadPage(BufferManager* manager) { Buffer* buffer = manager->getBuffer(bufferIndex()); buffer->seek(bufferPos()); __int32 bsize = buffer->readInt(); char* data = buffer->readChars(); MemoryStream* helperStream = new MemoryStream(data, bsize); helperStream->seek(0); helperStream->readInt(); // BUCKET_MAX_ELEMENTS size = helperStream->readInt(); IndexPage* tempPointer = NULL; for (int x = 0; x < BUCKET_MAX_ELEMENTS; x++) { Index* index = retrieveIndexElement(helperStream); elements[x] = index; tempPointer = retrievePointer(helperStream); pointers[x] = tempPointer; if (tempPointer != NULL) { tempPointer->parentElement = this; } } // Recovers the last pointer tempPointer = retrievePointer(helperStream); pointers[BUCKET_MAX_ELEMENTS] = tempPointer; if (tempPointer != NULL) { tempPointer->parentElement = this; } // Recovers siblings leftSibling = retrievePointer(helperStream); rightSibling = retrievePointer(helperStream); setLoaded(true); /* for (int x = 0; x <= BUCKET_MAX_ELEMENTS; x++) { IndexPage* temp = page->pointers[x]; if ((temp != NULL) && (temp->bufferIndex() > -1)) { loadPage(temp); } } */ delete helperStream; }
/** * Discards the current token, preparing it to be built anew. Also prints * an error message and the line the error occurred on. **/ void actError(state s, token *t, char c) { unsigned int pos = bufferPos(); fprintf(stdout, "(%d,%d): error: unexpected character ", bufferLineNumber(), pos); if (c == '\n') fprintf(stdout, "'\\n'\n"); else fprintf(stdout, "'%c'\n", c); bufferPrint(stdout); for (int i = 1; i < pos; i++) fprintf(stdout, " "); fprintf(stdout, "^\n"); tokenClean(t); tokenInit(t); }
void Mixer::resetBufs() { std::for_each(m_chips.begin(), m_chips.end(), bufferPos(0)); }