void FileReader::process (AudioSampleBuffer& buffer) { const int samplesNeededPerBuffer = int (float (buffer.getNumSamples()) * (getDefaultSampleRate() / m_sysSampleRate)); m_samplesPerBuffer.set(samplesNeededPerBuffer); // FIXME: needs to account for the fact that the ratio might not be an exact // integer value // if cache window id == 0, we need to read and cache BUFFER_WINDOW_CACHE_SIZE more buffer windows if (bufferCacheWindow == 0) { switchBuffer(); } for (int i = 0; i < currentNumChannels; ++i) { // offset readBuffer index by current cache window count * buffer window size * num channels input->processChannelData (*readBuffer + (samplesNeededPerBuffer * currentNumChannels * bufferCacheWindow), buffer.getWritePointer (i, 0), i, samplesNeededPerBuffer); } setTimestampAndSamples(timestamp, samplesNeededPerBuffer); timestamp += samplesNeededPerBuffer; static_cast<FileReaderEditor*> (getEditor())->setCurrentTime(samplesToMilliseconds(startSample + timestamp % (stopSample - startSample))); bufferCacheWindow += 1; bufferCacheWindow %= BUFFER_WINDOW_CACHE_SIZE; }
bool FileReader::enable() { timestamp = 0; AudioDeviceManager& adm = AccessClass::getAudioComponent()->deviceManager; AudioDeviceManager::AudioDeviceSetup ads; adm.getAudioDeviceSetup(ads); m_sysSampleRate = ads.sampleRate; m_bufferSize = ads.bufferSize; if (m_bufferSize == 0) m_bufferSize = 1024; m_samplesPerBuffer.set(m_bufferSize * (getDefaultSampleRate() / m_sysSampleRate)); bufferA.malloc(currentNumChannels * m_bufferSize * BUFFER_WINDOW_CACHE_SIZE); bufferB.malloc(currentNumChannels * m_bufferSize * BUFFER_WINDOW_CACHE_SIZE); readAndFillBufferCache(bufferA); // pre-fill the front buffer with a blocking read // set the backbuffer so that on the next call to process() we start with bufferA and buffer // cache window id = 0 readBuffer = &bufferB; bufferCacheWindow = 0; m_shouldFillBackBuffer.set(false); startThread(); // start async file reader thread return isEnabled; }
void GenericProcessor::clearSettings() { settings.originalSource = 0; settings.numInputs = 0; settings.numOutputs = 0; settings.sampleRate = getDefaultSampleRate(); channels.clear(); eventChannels.clear(); }
PaAudioDevice::PaAudioDevice(): defaultDeviceDId(-1){ chooseWiselyAndCreateNicely(); paOutputStream= std::move(util::UniquePtr<PaOutputStream>( new PaOutputStream( getDefaultStreamParameters(), getDefaultSampleRate(), getDefaultBufferSize() ) )); }
void FileReader::process (AudioSampleBuffer& buffer, MidiBuffer& events) { setTimestamp (events, timestamp); const int samplesNeeded = int (float (buffer.getNumSamples()) * (getDefaultSampleRate() / 44100.0f)); // FIXME: needs to account for the fact that the ratio might not be an exact // integer value int samplesRead = 0; while (samplesRead < samplesNeeded) { int samplesToRead = samplesNeeded - samplesRead; if ( (currentSample + samplesToRead) > stopSample) { samplesToRead = stopSample - currentSample; if (samplesToRead > 0) input->readData (readBuffer + samplesRead, samplesToRead); input->seekTo (startSample); currentSample = startSample; } else { input->readData (readBuffer + samplesRead, samplesToRead); currentSample += samplesToRead; } samplesRead += samplesToRead; } for (int i = 0; i < currentNumChannels; ++i) { input->processChannelData (readBuffer, buffer.getWritePointer (i, 0), i, samplesNeeded); } timestamp += samplesNeeded; setNumSamples (events, samplesNeeded); // code for testing events: // // =========================================================================== // if (counter == 100) // { // //std::cout << "Adding on event for node id: " << nodeId << std::endl; // addEvent (events, // MidiBuffer // TTL, // eventType // 0, // sampleNum // 1, // eventID // 0); // eventChannel // ++counter; // } // else if (counter > 120) // { // //std::cout << "Adding off event!" << std::endl; // addEvent (events, // MidiBuffer // TTL, // eventType // 0, // sampleNum // 0, // eventID // 0); // eventChannel // counter = 0; // } // else // { // ++counter; // } // // =========================================================================== }
void GenericProcessor::update() { std::cout << getName() << " updating settings." << std::endl; clearSettings(); if (sourceNode != 0) { // everything is inherited except numOutputs settings = sourceNode->settings; settings.numInputs = settings.numOutputs; settings.numOutputs = settings.numInputs; for (int i = 0; i < sourceNode->channels.size(); i++) { Channel* sourceChan = sourceNode->channels[i]; Channel* ch = new Channel(*sourceChan); ch->setProcessor(this); channels.add(ch); } for (int i = 0; i < sourceNode->eventChannels.size(); i++) { Channel* sourceChan = sourceNode->eventChannels[i]; Channel* ch = new Channel(*sourceChan); eventChannels.add(ch); } } else { settings.numOutputs = getDefaultNumOutputs(); settings.sampleRate = getDefaultSampleRate(); for (int i = 0; i < getNumOutputs(); i++) { Channel* ch = new Channel(this, i); ch->sampleRate = getDefaultSampleRate(); ch->bitVolts = getDefaultBitVolts(); channels.add(ch); } } if (this->isSink()) { settings.numOutputs = 0; } updateSettings(); // custom settings code // required for the ProcessorGraph to know the // details of this processor: setPlayConfigDetails(getNumInputs(), // numIns getNumOutputs(), // numOuts 44100.0, // sampleRate 128); // blockSize editor->update(); // update editor settings }