Esempio n. 1
0
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MetronomeTrackNode::processReplacing(const SamplesBuffer &in, SamplesBuffer &out,
                                          int SampleRate, const Midi::MidiBuffer &midiBuffer)
{
    if (samplesPerBeat <= 0)
        return;
    internalInputBuffer.setFrameLenght(out.getFrameLenght());
    internalInputBuffer.zero();

    SamplesBuffer *samplesBuffer = getBuffer(currentBeat);
    int samplesToCopy = std::min(
        (int)(samplesBuffer->getFrameLenght() - beatPosition), out.getFrameLenght());
    int nextBeatSample = beatPosition + out.getFrameLenght();
    int internalOffset = 0;
    int clickSoundBufferOffset = beatPosition;
    if (nextBeatSample > samplesPerBeat) {// next beat starting in this audio buffer?
        samplesBuffer = getBuffer(currentBeat + 1);
        internalOffset = samplesPerBeat - beatPosition;
        samplesToCopy = std::min(nextBeatSample - samplesPerBeat,
                                 (long)samplesBuffer->getFrameLenght());
        clickSoundBufferOffset = 0;
    }
    if (samplesToCopy > 0)
        internalInputBuffer.set(*samplesBuffer, clickSoundBufferOffset, samplesToCopy,
                                internalOffset);
    AudioNode::processReplacing(in, out, SampleRate, midiBuffer);
}
Esempio n. 2
0
void AudioNode::processReplacing(const SamplesBuffer &in, SamplesBuffer &out, int sampleRate, std::vector<midi::MidiMessage> &midiBuffer)
{
    Q_UNUSED(in);

    if (!isActivated())
        return;

    internalInputBuffer.setFrameLenght(out.getFrameLenght());
    internalOutputBuffer.setFrameLenght(out.getFrameLenght());

    {
        QMutexLocker locker(&mutex);
        for (auto node : connections) { // ask connected nodes to generate audio
            node->processReplacing(internalInputBuffer, internalOutputBuffer, sampleRate, midiBuffer);
        }
    }

    internalOutputBuffer.set(internalInputBuffer); // if we have no plugins inserted the input samples are just copied  to output buffer.

    static SamplesBuffer tempInputBuffer(2);

    // process inserted plugins
    for (int i=0; i < MAX_PROCESSORS_PER_TRACK; ++i) {
        auto processor = processors[i];
        if (processor && !processor->isBypassed()) {
            tempInputBuffer.setFrameLenght(internalOutputBuffer.getFrameLenght());
            tempInputBuffer.set(internalOutputBuffer); // the output from previous plugin is used as input to the next plugin in the chain

            processor->process(tempInputBuffer, internalOutputBuffer, midiBuffer);

            // some plugins are blocking the midi messages. If a VSTi can't generate messages the previous messages list will be sended for the next plugin in the chain. The messages list is cleared only when the plugin can generate midi messages.
            if (processor->isVirtualInstrument() && processor->canGenerateMidiMessages())
                midiBuffer.clear(); // only the fresh messages will be passed by the next plugin in the chain


            auto pulledMessages = pullMidiMessagesGeneratedByPlugins();
            midiBuffer.insert(midiBuffer.end(), pulledMessages.begin(), pulledMessages.end());
        }
    }

    preFaderProcess(internalOutputBuffer); //call overrided preFaderProcess in subclasses to allow some preFader process.

    internalOutputBuffer.applyGain(gain, leftGain, rightGain, boost);

    lastPeak.update(internalOutputBuffer.computePeak());

    postFaderProcess(internalOutputBuffer);

    out.add(internalOutputBuffer);
}
Esempio n. 3
0
void LooperLayer::setSamples(const SamplesBuffer &samples)
{
    zero();

    uint samplesToCopy = qMin(samples.getFrameLenght(), lastCycleLenght);
    if (!samplesToCopy) {
        return;
    }

    uint bytesToCopy =  samplesToCopy * sizeof(float);

    Q_ASSERT(leftChannel.capacity() >= samplesToCopy);
    Q_ASSERT(rightChannel.capacity() >= samplesToCopy);

    std::memcpy(&(leftChannel[0]), samples.getSamplesArray(0), bytesToCopy);
    if (samples.isMono())
        std::memcpy(&(rightChannel[0]), samples.getSamplesArray(0), bytesToCopy);
    else
        std::memcpy(&(rightChannel[0]), samples.getSamplesArray(1), bytesToCopy);

    availableSamples = samplesToCopy;


    // rebuild peaks cache
    lastCacheComputationSample = 0;
    peaksCache.clear();

    if (lastSamplesPerPeak) {
        while (availableSamples - lastCacheComputationSample >= lastSamplesPerPeak) { // enough samples to cache a new max peak?
            peaksCache.push_back(computeMaxPeak(lastCacheComputationSample, lastSamplesPerPeak));
            lastCacheComputationSample += lastSamplesPerPeak;
        }
    }

}
Esempio n. 4
0
void SamplesBuffer::set(const SamplesBuffer &buffer, int bufferChannelOffset, int channelsToCopy)
{
    if (buffer.channels <= 0 || channels <= 0)
        return;
    int framesToCopy = std::min(buffer.getFrameLenght(), (int)frameLenght);
    int channelsToProcess = std::min(channelsToCopy, std::min(buffer.getChannels(), (int)channels));
    if (channelsToProcess + bufferChannelOffset <= buffer.getChannels()) {// avoid invalid channel index
        int bytesToCopy = framesToCopy * sizeof(float);
        for (int c = 0; c < channelsToProcess; ++c)
            memcpy((void *)getSamplesArray(c), buffer.getSamplesArray(
                       c + bufferChannelOffset), bytesToCopy);
    }
}
Esempio n. 5
0
void SamplesBuffer::add(const SamplesBuffer &buffer, int internalWriteOffset)
{
    unsigned int framesToProcess = std::min((int)frameLenght, buffer.getFrameLenght());
    if (buffer.channels >= channels) {
        for (unsigned int c = 0; c < channels; ++c) {
            for (unsigned int s = 0; s < framesToProcess; ++s)
                samples[c][s + internalWriteOffset] += buffer.samples[c][s];
        }
    } else {// samples is stereo and buffer is mono
        for (unsigned int s = 0; s < framesToProcess; ++s) {
            samples[0][s + internalWriteOffset] += buffer.samples[0][s];
            samples[1][s + internalWriteOffset] += buffer.samples[0][s];
        }
    }
}
Esempio n. 6
0
void SamplesBuffer::set(const SamplesBuffer &buffer, int bufferChannelOffset, int channelsToCopy)
{
    if (buffer.channels == 0 || channels == 0)
        return;

    int framesToCopy = std::min(buffer.getFrameLenght(), frameLenght);
    int channelsToProcess = std::min(channelsToCopy, std::min(buffer.getChannels(), static_cast<int>(channels)));

    if (channelsToProcess + bufferChannelOffset > buffer.getChannels())
        return; // avoid crash acessing invalid memory

    int bytesToCopy = framesToCopy * sizeof(float);
    for (int c = 0; c < channelsToProcess; ++c) {
        memcpy((void *)getSamplesArray(c), buffer.getSamplesArray(c + bufferChannelOffset), bytesToCopy);
    }
}
Esempio n. 7
0
void SamplesBuffer::set(const SamplesBuffer& buffer, unsigned int bufferOffset, unsigned int samplesToCopy, unsigned int internalOffset){

    if(buffer.channels <= 0 || channels <= 0){
        return;
    }

    unsigned int framesToProcess = std::min(samplesToCopy, buffer.getFrameLenght() - bufferOffset);
    if(framesToProcess > buffer.frameLenght){//não processa mais samples do que a quantidade existente em buffer
        framesToProcess = buffer.frameLenght;
    }
    if((int)(internalOffset + framesToProcess)  > this->getFrameLenght()){
        framesToProcess = (internalOffset + framesToProcess) - this->getFrameLenght();
    }

    if(channels == buffer.channels){//channels number are equal
        for (unsigned int c = 0; c < channels; ++c) {
            for (unsigned int s = 0; s < framesToProcess; ++s) {
                samples[c][s + internalOffset] = buffer.samples[c][s + bufferOffset];
            }
        }
    }
    else{//different number of channels
        if(!isMono()){//copy every &buffer samples to LR in this buffer
            if(!buffer.isMono()){
                int channelsToCopy = qMin(channels, buffer.channels);
                for (int c = 0; c < channelsToCopy; ++c) {
                    for (unsigned int s = 0; s < framesToProcess; ++s) {
                        samples[c][s + internalOffset] = buffer.samples[c][s + bufferOffset];
                    }
                }
            }
            else{
                for (unsigned int s = 0; s < framesToProcess; ++s) {
                    samples[0][s + internalOffset] = buffer.samples[0][s + bufferOffset];
                    samples[1][s + internalOffset] = buffer.samples[0][s + bufferOffset];
                }
            }
        }
        else{//this buffer is mono, but the buffer in parameter is not! Mix down the stereo samples in one mono sample value.
            for (unsigned int s = 0; s < framesToProcess; ++s) {
                samples[0][s + internalOffset] = (buffer.samples[0][s + bufferOffset] + buffer.samples[1][s + bufferOffset]) / 2;
            }
        }
    }

}
Esempio n. 8
0
void SamplesBuffer::set(const SamplesBuffer &buffer, uint bufferOffset, uint samplesToCopy, uint internalOffset)
{
    if (buffer.channels == 0 || channels == 0)
        return;

    unsigned int framesToProcess = std::min(samplesToCopy, buffer.getFrameLenght() - bufferOffset);
    if (framesToProcess + bufferOffset > buffer.frameLenght) // fixing bug in some built-in metronome sounds
        return ;

    if ((uint)(internalOffset + framesToProcess) > this->getFrameLenght())
        framesToProcess = (internalOffset + framesToProcess) - this->getFrameLenght();

    const uint bytesToProcess = framesToProcess * sizeof(float);
    if (!bytesToProcess)
        return;

    if (channels == buffer.channels) {// channels number are equal
        for (unsigned int c = 0; c < channels; ++c) {
            std::memcpy(&(samples[c][internalOffset]), &(buffer.samples[c][bufferOffset]), bytesToProcess);
        }
    }
    else { // different number of channels
        if (!isMono()) { // copy every &buffer samples to LR in this buffer
            if (!buffer.isMono()) {
                int channelsToCopy = qMin(channels, buffer.channels);
                for (int c = 0; c < channelsToCopy; ++c) {
                    Q_ASSERT(internalOffset < samples[c].size());
                    Q_ASSERT(bufferOffset < buffer.samples[c].size());
                    Q_ASSERT(bufferOffset + framesToProcess < buffer.samples[c].size());
                    Q_ASSERT(internalOffset + framesToProcess < samples[c].size());
                    std::memcpy(&(samples[c][internalOffset]), &(buffer.samples[c][bufferOffset]), bytesToProcess);
                }
            } else {
                std::memcpy(&(samples[0][internalOffset]), &(buffer.samples[0][bufferOffset]), bytesToProcess);
                std::memcpy(&(samples[1][internalOffset]), &(buffer.samples[0][bufferOffset]), bytesToProcess);
            }
        } else { // this buffer is mono, but the buffer in parameter is not! Mix down the stereo samples in one mono sample value.
            for (unsigned int s = 0; s < framesToProcess; ++s) {
                const int index = s + bufferOffset;
                float v = (buffer.samples[0][index] + buffer.samples[1][index])/2.0f;
                samples[0][s + internalOffset] = v;
            }
        }
    }
}
Esempio n. 9
0
void SamplesBuffer::add(const SamplesBuffer &buffer, int internalWriteOffset){
    //QMutexLocker locker(&mutex);
    unsigned int framesToProcess = std::min( (int)frameLenght, buffer.getFrameLenght());
//    if(framesToProcess < (unsigned int)buffer.getFrameLenght()){
//        qWarning() << (buffer.getFrameLenght()-framesToProcess) << " samples discarded";
//    }
    if( buffer.channels >= channels){
        for (unsigned int c = 0; c < channels; ++c) {
            for (unsigned int s = 0; s < framesToProcess; ++s) {
                samples[c][s + internalWriteOffset] += buffer.samples[c][s];
            }
        }
    }
    else{//samples is stereo and buffer is mono
        for (unsigned int s = 0; s < framesToProcess; ++s) {
            samples[0][s + internalWriteOffset] += buffer.samples[0][s];
            samples[1][s + internalWriteOffset] += buffer.samples[0][s];
        }
    }
}