TErrors SalsaStream::read(llaAudioPipe& buffer) {
	if(pcm_state_ == CLOSED) {
		LOGGER().warning(E_READ_STREAM, "Attempt to write to a closed stream.");
		return E_READ_STREAM;
	}

	TErrors err;
	if( (err = updateSettings(buffer)) != E_OK) return err;


	char *iraw, **niraw;
	int rc;
	getRawInputBuffers(buffer, &iraw, &niraw);

	if(organization_ == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
		rc = snd_pcm_readn(pcm_, (void**)niraw, buffer.getBufferLength());

	}
	else {
		rc = snd_pcm_readi(pcm_, (void*)iraw, buffer.getBufferLength());
	}

	setBufferLastWrite(buffer, rc);
	if (rc == -EPIPE) {
	  /* EPIPE means underrun */
	  snd_pcm_prepare(pcm_);
	} else if (rc < 0) {
		LOGGER().warning(E_READ_STREAM, snd_strerror(rc));
		snd_pcm_recover(pcm_, rc, 0);
	}


	return E_OK;
}
Beispiel #2
0
    bool readFromInputDevice (AudioBuffer<float>& inputChannelBuffer, const int numSamples)
    {
        jassert (numChannelsRunning <= inputChannelBuffer.getNumChannels());
        float* const* const data = inputChannelBuffer.getArrayOfWritePointers();

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

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

            if (num < 0)
            {
                if (num == -(EPIPE))
                    overrunCount++;

                if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
                    return false;
            }


            if (num < numSamples)
                JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples);

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

            if (num < 0)
            {
                if (num == -(EPIPE))
                    overrunCount++;

                if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
                    return false;
            }

            if (num < numSamples)
                JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples);

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

        return true;
    }
static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
	snd_pcm_file_t *file = pcm->private_data;
	snd_pcm_channel_area_t areas[pcm->channels];
	snd_pcm_sframes_t n;

	if (file->ifd >= 0) {
		SNDERR("DEBUG: Noninterleaved read not yet implemented.\n");
		return 0;	/* TODO: Noninterleaved read */
	}

	n = snd_pcm_readn(file->gen.slave, bufs, size);
	if (n > 0) {
		snd_pcm_areas_from_bufs(pcm, areas, bufs);
		snd_pcm_file_add_frames(pcm, areas, 0, n);
	}
	return n;
}
    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;
    }
Beispiel #5
0
snd_pcm_sframes_t snd_pcm_generic_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
{
    snd_pcm_generic_t *generic = pcm->private_data;
    return snd_pcm_readn(generic->slave, bufs, size);
}
TErrors SalsaStream::connect( llaOutputStream* output, llaAudioPipe& buffer) {



	TErrors ret = _open(SND_PCM_NONBLOCK);
	// Update pcm settings
	if( ret != E_OK || (ret = updateSettings(buffer)) != E_OK ) return ret;

	if( (ret = output->open()) != E_OK ) {
		close();
		return ret;
	}

	int err = 0;

	snd_pcm_uframes_t avail_min = 0;
	if(buffer.getBufferLength() < period_size_) {
		close();
		output->close();
		LOGGER().error(E_STREAM_CONFIG, "Buffer length must be higher");
		return E_STREAM_CONFIG;
	}
	else if(buffer.getBufferLength() / period_size_ < 3 ) avail_min = period_size_;
	else avail_min = ((buffer.getBufferLength()/period_size_)-2)*period_size_;



	// Set up the input stream for polling /////////////////////////////////////
	// This is the same process as for the output.

	err = snd_pcm_sw_params_malloc(&sw_config_);
	err = snd_pcm_sw_params_current(pcm_, sw_config_);
	CHECK_SNDERROR(err, E_STREAM_CONFIG);

//	err = snd_pcm_sw_params_set_start_threshold (pcm_, sw_config_, 0U );
//	CHECK_SNDERROR(err, E_STREAM_CONFIG);

	err = snd_pcm_sw_params_set_avail_min(pcm_, sw_config_, avail_min  );
	CHECK_SNDERROR(err, E_STREAM_CONFIG);

	err = snd_pcm_sw_params(pcm_, sw_config_);
	CHECK_SNDERROR(err, E_STREAM_CONFIG);

	snd_pcm_prepare(pcm_);

	snd_pcm_uframes_t frames;

	char *iraw, **niraw;

	while(!buffer.stop() && !buffer.fail()) {
		snd_pcm_start(pcm_);
		if ((err = snd_pcm_wait (pcm_, -1)) < 0) {
			if (err == -EPIPE) {
			  /* EPIPE means xrun */
			  snd_pcm_prepare(pcm_);
			} else if (err < 0) {
				LOGGER().error(E_READ_STREAM, snd_strerror(err));
				snd_pcm_sw_params_free(sw_config_);
				close();
				output->close();
				return E_READ_STREAM;
			}
		}

		frames = snd_pcm_avail_update(pcm_);
		if(frames < 0) {
			LOGGER().error(E_READ_STREAM, snd_strerror(err));
			snd_pcm_sw_params_free(sw_config_);
			close();
			output->close();
			return E_READ_STREAM;
		}

		if(frames > buffer.getBufferLength()) frames = buffer.getBufferLength();

		int rc;
		getRawInputBuffers( buffer, &iraw, &niraw);

		// read from the stream
		if(organization_ == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
			rc = snd_pcm_readn(pcm_, (void**)niraw, frames);
		}
		else {
			rc = snd_pcm_readi(pcm_, (void*)iraw, frames);
		}

		// save the number of frames read
		TSize lastwrite = ((TSize)rc <= buffer.getBufferLength())?
				rc : buffer.getBufferLength();

		setBufferLastWrite(buffer, lastwrite);

		// detect errors
		if (rc == -EPIPE) {
		  /* EPIPE means underrun */
		  snd_pcm_prepare(pcm_);
		} else if (rc < 0) {
			LOGGER().warning(E_READ_STREAM, snd_strerror(rc));
			snd_pcm_sw_params_free(sw_config_);
			close();
			output->close();
			return E_READ_STREAM;
		}

		TErrors reterr;
		if( (reterr=output->write(buffer)) != E_OK ) {
			snd_pcm_sw_params_free(sw_config_);
			close();
			output->close();
		}

	}

	snd_pcm_sw_params_free(sw_config_);
	close();
	output->close();

	return E_OK;
}