void run()
    {
        const int bufferSize = currentBufferSizeSamples;

        HANDLE events[2];
        int numEvents = 0;
        if (inputDevice != 0)
            events [numEvents++] = inputDevice->clientEvent;
        if (outputDevice != 0)
            events [numEvents++] = outputDevice->clientEvent;

        const int numInputBuffers = getActiveInputChannels().countNumberOfSetBits();
        const int numOutputBuffers = getActiveOutputChannels().countNumberOfSetBits();

        AudioSampleBuffer ins (jmax (1, numInputBuffers), bufferSize + 32);
        AudioSampleBuffer outs (jmax (1, numOutputBuffers), bufferSize + 32);
        float** const inputBuffers = ins.getArrayOfChannels();
        float** const outputBuffers = outs.getArrayOfChannels();
        ins.clear();

        while (! threadShouldExit())
        {
            const DWORD result = WaitForMultipleObjects (numEvents, events, true, 1000);

            if (result == WAIT_TIMEOUT)
                continue;

            if (threadShouldExit())
                break;

            if (inputDevice != 0)
                inputDevice->copyBuffers (inputBuffers, numInputBuffers, bufferSize, *this);

            // Make the callback..
            {
                const ScopedLock sl (startStopLock);

                if (isStarted)
                {
                    JUCE_TRY
                    {
                        callback->audioDeviceIOCallback ((const float**) inputBuffers,
                                                         numInputBuffers,
                                                         outputBuffers,
                                                         numOutputBuffers,
                                                         bufferSize);
                    }
                    JUCE_CATCH_EXCEPTION
                }
                else
                {
                    outs.clear();
                }
            }

            if (outputDevice != 0)
                outputDevice->copyBuffers ((const float**) outputBuffers, numOutputBuffers, bufferSize, *this);
        }
Example #2
0
bool AudioFormatWriter::writeFromAudioSampleBuffer (const AudioSampleBuffer& source, int startSample, int numSamples)
{
    const int numSourceChannels = source.getNumChannels();
    jassert (startSample >= 0 && startSample + numSamples <= source.getNumSamples() && numSourceChannels > 0);

    if (startSample == 0)
        return writeFromFloatArrays ((const float**) source.getArrayOfChannels(), numSourceChannels, numSamples);

    const float* chans [256];
    jassert ((int) numChannels < numElementsInArray (chans));

    for (int i = 0; i < numSourceChannels; ++i)
        chans[i] = source.getSampleData (i, startSample);

    chans[numSourceChannels] = nullptr;

    return writeFromFloatArrays (chans, numSourceChannels, numSamples);
}
Example #3
0
void FilterNode::process(AudioSampleBuffer &buffer, 
                            MidiBuffer &midiMessages,
                            int& nSamples)
{
	//std::cout << "Filter node processing." << std::endl;
	//std::cout << buffer.getNumChannels() << std::endl;
	//::cout << buffer.getNumSamples() << std::endl;

	//int nSamps = getNumSamples(midiMessages);
	//std::cout << nSamples << std::endl;
    filter->process (nSamples, buffer.getArrayOfChannels());

    //std::cout << "Filter node:" << *buffer.getSampleData(0,0);


    //int ts = checkForMidiEvents(midiMessages);

    //std::cout << "Timestamp = " << ts << std::endl;
}
Example #4
0
void DemoJuceFilter::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{	
	assert(mpDSP->getNumInputs()<= buffer.getNumChannels());
	assert(mpDSP->getNumOutputs()<= buffer.getNumChannels());
	if(mpDSP	&& mpDSP->getNumInputs()<= buffer.getNumChannels() 
						&& mpDSP->getNumOutputs() <= buffer.getNumChannels() )
	{
		mpDSP->compute(buffer.getNumSamples(), 
									 buffer.getArrayOfChannels(), 
									 buffer.getArrayOfChannels());
	}
	
	// in case we have more outputs than inputs, we'll clear any output
	// channels that didn't contain input data, (because these aren't
	// guaranteed to be empty - they may contain garbage).
	for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
	{
		buffer.clear (i, 0, buffer.getNumSamples());
	}
}
    bool readFromInputDevice (AudioSampleBuffer& inputChannelBuffer, const int numSamples)
    {
        jassert (numChannelsRunning <= inputChannelBuffer.getNumChannels());
        float** const data = inputChannelBuffer.getArrayOfChannels();

        if (isInterleaved)
        {
            scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false);
            scratch.fillWith (0); // (not clearing this data causes warnings in valgrind)

            snd_pcm_sframes_t num = snd_pcm_readi (handle, scratch.getData(), numSamples);

            if (failed (num))
            {
                if (num == -EPIPE)
                {
                    if (failed (snd_pcm_prepare (handle)))
                        return false;
                }
                else if (num != -ESTRPIPE)
                    return false;
            }

            for (int i = 0; i < numChannelsRunning; ++i)
                converter->convertSamples (data[i], 0, scratch.getData(), i, numSamples);
        }
        else
        {
            snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, numSamples);

            if (failed (num) && num != -EPIPE && num != -ESTRPIPE)
                return false;

            for (int i = 0; i < numChannelsRunning; ++i)
                converter->convertSamples (data[i], data[i], numSamples);
        }

        return true;
    }
    //==============================================================================
    bool writeToOutputDevice (AudioSampleBuffer& outputChannelBuffer, const int numSamples)
    {
        jassert (numChannelsRunning <= outputChannelBuffer.getNumChannels());
        float** const data = outputChannelBuffer.getArrayOfChannels();
        snd_pcm_sframes_t numDone = 0;

        if (isInterleaved)
        {
            scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false);

            for (int i = 0; i < numChannelsRunning; ++i)
                converter->convertSamples (scratch.getData(), i, data[i], 0, numSamples);

            numDone = snd_pcm_writei (handle, scratch.getData(), numSamples);
        }
        else
        {
            for (int i = 0; i < numChannelsRunning; ++i)
                converter->convertSamples (data[i], data[i], numSamples);

            numDone = snd_pcm_writen (handle, (void**) data, numSamples);
        }

        if (failed (numDone))
        {
            if (numDone == -EPIPE)
            {
                if (failed (snd_pcm_prepare (handle)))
                    return false;
            }
            else if (numDone != -ESTRPIPE)
                return false;
        }

        return true;
    }
Example #7
0
void ResamplingNode::process(AudioSampleBuffer& buffer,
                             MidiBuffer& midiMessages,
                             int& nSamples)
{

    //std::cout << "Resampling node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;

    // save data at the beginning of each round of processing
    //writeContinuousBuffer(buffer.getSampleData(0), nSamples, 0);


    int nSamps = float(nSamples);
    int valuesNeeded = int(nSamps / ratio);

    if (ratio > 1.0001)
    {
        // pre-apply filter before downsampling
        filter->process(nSamples, buffer.getArrayOfChannels());
    }

    // initialize variables
    tempBuffer->clear();
    int sourceBufferPos = 0;
    int sourceBufferSize = buffer.getNumSamples();
    float subSampleOffset = 0.0;
    int nextPos = (sourceBufferPos + 1) % sourceBufferSize;

    int tempBufferPos;

    // code modified from "juce_ResamplingAudioSource.cpp":

    for (tempBufferPos = 0; tempBufferPos < valuesNeeded; tempBufferPos++)
    {
        float gain = 1.0;
        float alpha = (float) subSampleOffset;
        float invAlpha = 1.0f - alpha;

        for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
        {

            tempBuffer->addFrom(channel, 		// destChannel
                                tempBufferPos,  // destSampleOffset
                                buffer,			// source
                                channel,		// sourceChannel
                                sourceBufferPos,// sourceSampleOffset
                                1,				// number of samples
                                invAlpha*gain);      // gain to apply to source

            tempBuffer->addFrom(channel, 		// destChannel
                                tempBufferPos,   // destSampleOffset
                                buffer,			// source
                                channel,			// sourceChannel
                                nextPos,		 	// sourceSampleOffset
                                1,				// number of samples
                                alpha*gain);     	 // gain to apply to source

        }

        subSampleOffset += ratio;

        while (subSampleOffset >= 1.0)
        {
            if (++sourceBufferPos >= sourceBufferSize)
                sourceBufferPos = 0;

            nextPos = (sourceBufferPos + 1) % sourceBufferSize;
            subSampleOffset -= 1.0;
        }
    }

    // std::cout << sourceBufferPos << " " << tempBufferPos << std::endl;


    if (ratio < 0.9999)
    {

        filter->process(tempBufferPos, tempBuffer->getArrayOfChannels());
        // apply the filter after upsampling
        ///////filter->process (totalSamples, buffer.getArrayOfChannels());
    }
    else if (ratio <= 1.0001)
    {

        // no resampling is being applied, no need to filter, BUT...
        // keep the filter stoked with samples to avoid discontinuities

    }

    // copy the tempBuffer back into the original buffer
    buffer = AudioSampleBuffer(tempBuffer->getArrayOfChannels(), 2, tempBufferPos);//buffer.getNumSamples());

    nSamples = valuesNeeded;

}
void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples,
                                       float& lowestLeft, float& highestLeft,
                                       float& lowestRight, float& highestRight)
{
    if (numSamples <= 0)
    {
        lowestLeft = 0;
        lowestRight = 0;
        highestLeft = 0;
        highestRight = 0;
        return;
    }

    const int bufferSize = (int) jmin (numSamples, (int64) 4096);
    AudioSampleBuffer tempSampleBuffer (numChannels, bufferSize);

    float** const floatBuffer = tempSampleBuffer.getArrayOfChannels();
    int* const* intBuffer = reinterpret_cast<int* const*> (floatBuffer);

    if (usesFloatingPointData)
    {
        float lmin = 1.0e6f;
        float lmax = -lmin;
        float rmin = lmin;
        float rmax = lmax;

        while (numSamples > 0)
        {
            const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
            if (! read (intBuffer, 2, startSampleInFile, numToDo, false))
                break;

            numSamples -= numToDo;
            startSampleInFile += numToDo;
            getStereoMinAndMax (floatBuffer, numChannels, numToDo, lmin, lmax, rmin, rmax);
        }

        lowestLeft   = lmin;
        highestLeft  = lmax;
        lowestRight  = rmin;
        highestRight = rmax;
    }
    else
    {
        int lmax = std::numeric_limits<int>::min();
        int lmin = std::numeric_limits<int>::max();
        int rmax = std::numeric_limits<int>::min();
        int rmin = std::numeric_limits<int>::max();

        while (numSamples > 0)
        {
            const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
            if (! read (intBuffer, 2, startSampleInFile, numToDo, false))
                break;

            numSamples -= numToDo;
            startSampleInFile += numToDo;
            getStereoMinAndMax (intBuffer, numChannels, numToDo, lmin, lmax, rmin, rmax);
        }

        lowestLeft   = lmin / (float) std::numeric_limits<int>::max();
        highestLeft  = lmax / (float) std::numeric_limits<int>::max();
        lowestRight  = rmin / (float) std::numeric_limits<int>::max();
        highestRight = rmax / (float) std::numeric_limits<int>::max();
    }
}
Example #9
0
void AudioResamplingNode::process(AudioSampleBuffer& buffer,
                                  MidiBuffer& midiMessages,
                                  int& nSamples)
{

    int nSamps = nSamples;
    int valuesNeeded;

    if (destBufferIsTempBuffer)
    {
        ratio = float(nSamps) / float(buffer.getNumSamples());
        valuesNeeded = buffer.getNumSamples();
    }
    else
    {
        ratio = sourceBufferSampleRate / destBufferSampleRate;
        valuesNeeded = (int) buffer.getNumSamples() / ratio;
        //std::cout << std::endl;
        //std::cout << "Ratio: " << ratio << std::endl;
        //std::cout << "Values needed: " << valuesNeeded << std::endl;
    }



    if (lastRatio != ratio)
    {
        updateFilter();
        lastRatio = ratio;
    }


    if (ratio > 1.0001)
    {
        // pre-apply filter before downsampling
        filter->process(nSamps, buffer.getArrayOfChannels());
    }


    // initialize variables
    tempBuffer->clear();
    int sourceBufferPos = 0;
    int sourceBufferSize = buffer.getNumSamples();
    float subSampleOffset = 0.0;
    int nextPos = (sourceBufferPos + 1) % sourceBufferSize;

    int tempBufferPos;
    //int totalSamples = 0;

    // code modified from "juce_ResamplingAudioSource.cpp":

    for (tempBufferPos = 0; tempBufferPos < valuesNeeded; tempBufferPos++)
    {
        float gain = 1.0;
        float alpha = (float) subSampleOffset;
        float invAlpha = 1.0f - alpha;

        for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
        {

            tempBuffer->addFrom(channel, 		// destChannel
                                tempBufferPos,  // destSampleOffset
                                buffer,			// source
                                channel,		// sourceChannel
                                sourceBufferPos,// sourceSampleOffset
                                1,				// number of samples
                                invAlpha*gain);      // gain to apply to source

            tempBuffer->addFrom(channel, 		// destChannel
                                tempBufferPos,   // destSampleOffset
                                buffer,			// source
                                channel,			// sourceChannel
                                nextPos,		 	// sourceSampleOffset
                                1,				// number of samples
                                alpha*gain);     	 // gain to apply to source

        }

        subSampleOffset += ratio;



        while (subSampleOffset >= 1.0)
        {
            if (++sourceBufferPos >= sourceBufferSize)
                sourceBufferPos = 0;

            nextPos = (sourceBufferPos + 1) % sourceBufferSize;
            subSampleOffset -= 1.0;
        }
    }

    // std::cout << sourceBufferPos << " " << tempBufferPos << std::endl;


    if (ratio < 0.9999)
    {

        filter->process(tempBufferPos, tempBuffer->getArrayOfChannels());
        // apply the filter after upsampling
        ///////filter->process (totalSamples, buffer.getArrayOfChannels());
    }
    else if (ratio <= 1.0001)
    {

        // no resampling is being applied, no need to filter, BUT...
        // keep the filter stoked with samples to avoid discontinuities

    }

    if (destBufferIsTempBuffer)
    {

        // copy the temp buffer into the original buffer
        buffer = AudioSampleBuffer(tempBuffer->getArrayOfChannels(), 2, tempBufferPos);//buffer.getNumSamples());

    }
    else
    {

        //std::cout << "Copying into dest buffer..." << std::endl;

        // copy the temp buffer into the destination buffer

        int pos = 0;

        while (*tempBuffer->getSampleData(0,pos) != 0)
            pos++;

        int spaceAvailable = destBufferWidth - destBufferPos;
        int blockSize1 = (spaceAvailable > pos) ? pos : spaceAvailable;
        int blockSize2 = (spaceAvailable > pos) ? 0 : (pos - spaceAvailable);

        for (int channel = 0; channel < destBuffer->getNumChannels(); channel++)
        {

            // copy first block
            destBuffer->copyFrom(channel, 		//destChannel
                                 destBufferPos, //destStartSample
                                 *tempBuffer, 	//source
                                 channel, 		//sourceChannel
                                 0, 			//sourceStartSample
                                 blockSize1  //numSamples
                                );

            // copy second block
            destBuffer->copyFrom(channel, 		//destChannel
                                 0, 			//destStartSample
                                 *tempBuffer, 	//source
                                 channel, 		//sourceChannel
                                 blockSize1, 	//sourceStartSample
                                 blockSize2  //numSamples
                                );

        }

        //destBufferPos = (spaceAvailable > tempBufferPos) ? destBufferPos

        destBufferPos += pos;
        destBufferPos %= destBufferWidth;

        //std::cout << "Temp buffer position: " << tempBufferPos << std::endl;
        //std::cout << "Resampling node value:" << *destBuffer->getSampleData(0,0) << std::endl;

    }

}