Beispiel #1
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;
        }
    }

}
Beispiel #2
0
void LooperLayer::append(const SamplesBuffer &samples, uint samplesToAppend, uint startPosition)
{
    int toAppend = qMin(static_cast<uint>(leftChannel.capacity() - startPosition), samplesToAppend);

    if (!toAppend) {
        qCritical() << "toAppend:" << toAppend;
        return;
    }

    const uint sizeInBytes = toAppend * sizeof(float);

    const int secondChannelIndex = samples.isMono() ? 0 : 1;
    std::memcpy(&(leftChannel[0]) + startPosition, samples.getSamplesArray(0), sizeInBytes);
    std::memcpy(&(rightChannel[0]) + startPosition, samples.getSamplesArray(secondChannelIndex), sizeInBytes);

    availableSamples += toAppend;

    //Q_ASSERT(availableSamples <= leftChannel.capacity());

    // build peaks cache
    if (lastSamplesPerPeak) {
        if (lastCacheComputationSample < startPosition - lastSamplesPerPeak)
            lastCacheComputationSample = startPosition;

        while ((startPosition + samplesToAppend) - lastCacheComputationSample >= lastSamplesPerPeak && lastCacheComputationSample  < leftChannel.size()) { // enough samples to cache a new max peak?
            peaksCache.push_back(computeMaxPeak(lastCacheComputationSample, lastSamplesPerPeak));
            lastCacheComputationSample += lastSamplesPerPeak;
        }
    }
}
Beispiel #3
0
void LooperLayer::mixTo(SamplesBuffer &outBuffer, uint samplesToMix, uint intervalPosition, float looperMainGain)
{
    bool canMix = samplesToMix > 0 && (muteState == LooperLayer::Unmuted || muteState == LooperLayer::WaitingToMute);
    if (canMix) {
        float *internalChannels[] = {&(leftChannel[0]), &(rightChannel[0])};
        const uint secondChannelIndex = (outBuffer.isMono()) ? 0 : 1;
        float *bufferChannels[] = {outBuffer.getSamplesArray(0), outBuffer.getSamplesArray(secondChannelIndex)};
        uint channels = outBuffer.getChannels();

        const float mainGain = looperMainGain * gain;
        const float finalLeftGain = mainGain * leftGain;
        const float finalRightGain = mainGain * rightGain;
        float gains[] = {finalLeftGain, finalRightGain};
        for (uint c = 0; c < channels; ++c) {
            for (uint s = 0; s < samplesToMix; ++s) {
                const uint offset = s + intervalPosition;
                bufferChannels[c][s] += internalChannels[c][offset] * gains[c];
            }
        }
    }
}
Beispiel #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);
    }
}
SamplesBuffer *createResampledBuffer(const SamplesBuffer &buffer, int originalSampleRate,
                                     int finalSampleRate)
{
    int finalSize = (double)finalSampleRate/originalSampleRate * buffer.getFrameLenght();
    int channels = buffer.getChannels();
    SamplesBuffer *newBuffer = new SamplesBuffer(channels, finalSize);
    for (int c = 0; c < channels; ++c) {
        ResamplerTest resampler;
        resampler.process(buffer.getSamplesArray(c),
                          buffer.getFrameLenght(), newBuffer->getSamplesArray(c), finalSize);
    }
    return newBuffer;
}
Beispiel #6
0
void LooperLayer::overdub(const SamplesBuffer &samples, uint samplesToMix, uint startPosition)
{
    if (!samples.isMono()) {
        float *internalChannels[] = {&(leftChannel[startPosition]), &(rightChannel[startPosition])};
        float *samplesArray[] = {samples.getSamplesArray(0), samples.getSamplesArray(1)};
        for (uint s = 0; s < samplesToMix; ++s) {
            internalChannels[0][s] += samplesArray[0][s]; // left channel
            internalChannels[1][s] += samplesArray[1][s]; // right channel
        }
    }
    else {
        float *internalChannels[] = {&(leftChannel[startPosition]), &(rightChannel[startPosition])};
        float *samplesArray = samples.getSamplesArray(0);
        for (uint s = 0; s < samplesToMix; ++s) {
            internalChannels[0][s] += samplesArray[s];
        }
    }

    if (availableSamples < startPosition + samplesToMix)
        availableSamples = startPosition + samplesToMix;

    // build peaks cache when overdubbing
    if (lastSamplesPerPeak) {
        const uint position = startPosition + samplesToMix;
        while (position - lastCacheComputationSample >= lastSamplesPerPeak) { // enough samples to cache a new max peak?
            const int peakIndex = (position/lastSamplesPerPeak) - 1;
            float lastPeak = computeMaxPeak(lastCacheComputationSample, lastSamplesPerPeak);
            if (peakIndex >= 0 && static_cast<uint>(peakIndex) < peaksCache.size())
                peaksCache[peakIndex] = lastPeak;
            else
                peaksCache.push_back(lastPeak);

            lastCacheComputationSample += lastSamplesPerPeak;
        }
    }
}
Beispiel #7
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);
    }
}