示例#1
0
static PaError
BlockingWriteStream(PaStream* stream, const void *data, unsigned long numFrames)
{
	PaSndioStream *s = (PaSndioStream *)stream;
	unsigned n, res;

	while (numFrames > 0) {
		n = s->par.round;
		if (n > numFrames)
			n = numFrames;
		PaUtil_SetOutputFrameCount(&s->bufproc, n);
		PaUtil_SetInterleavedOutputChannels(&s->bufproc, 0, s->wbuf, s->par.pchan);
		res = PaUtil_CopyOutput(&s->bufproc, &data, n);
		if (res != n) {
			DPR("BlockingWriteStream: copyOutput: %u != %u\n");
			return paUnanticipatedHostError;
		}
		res = sio_write(s->hdl, s->wbuf, n * s->par.pchan * s->par.bps);
		if (res == 0)
			return paUnanticipatedHostError;		
		s->wpos += n;
		numFrames -= n;
	}
	return paNoError;
}
示例#2
0
/*
    ExampleHostProcessingLoop() illustrates the kind of processing which may
    occur in a host implementation.
 
*/
static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
{
    PaSkeletonStream *stream = (PaSkeletonStream*)userData;
    PaTimestamp outTime = 0; /* IMPLEMENT ME */
    int callbackResult;
    unsigned long framesProcessed;
    
    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
    
    /*
        IMPLEMENT ME:
            - generate timing information
            - handle buffer slips
    */

    /*
        If you need to byte swap or shift inputBuffer to convert it into a
        portaudio format, do it here.
    */



    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, outTime );

    /*
        depending on whether the host buffers are interleaved, non-interleaved
        or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
        PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
    */
    
    PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
            0, /* first channel of inputBuffer is channel 0 */
            inputBuffer,
            0 ); /* 0 - use numInputChannels passed to init buffer processor */

    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
            0, /* first channel of outputBuffer is channel 0 */
            outputBuffer,
            0 ); /* 0 - use numOutputChannels passed to init buffer processor */

    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );

    
    /*
        If you need to byte swap or shift outputBuffer to convert it to
        host format, do it here.
    */

    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );


    if( callbackResult == paContinue )
    {
        /* nothing special to do */
    }
    else if( callbackResult == paAbort )
    {
        /* IMPLEMENT ME - finish playback immediately  */
    }
    else
    {
        /* User callback has asked us to stop with paComplete or other non-zero value */

        /* IMPLEMENT ME - finish playback once currently queued audio has completed  */
    }
}
示例#3
0
/*
    ExampleHostProcessingLoop() illustrates the kind of processing which may
    occur in a host implementation.
 
*/
static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
{
    PaSkeletonStream *stream = (PaSkeletonStream*)userData;
    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */
    int callbackResult;
    unsigned long framesProcessed;
    
    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
    
    /*
        IMPLEMENT ME:
            - generate timing information
            - handle buffer slips
    */

    /*
        If you need to byte swap or shift inputBuffer to convert it into a
        portaudio format, do it here.
    */



    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ );

    /*
        depending on whether the host buffers are interleaved, non-interleaved
        or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
        PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
    */
    
    PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
            0, /* first channel of inputBuffer is channel 0 */
            inputBuffer,
            0 ); /* 0 - use inputChannelCount passed to init buffer processor */

    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
            0, /* first channel of outputBuffer is channel 0 */
            outputBuffer,
            0 ); /* 0 - use outputChannelCount passed to init buffer processor */

    /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing()
        in general you would pass paContinue for normal operation, and
        paComplete to drain the buffer processor's internal output buffer.
        You can check whether the buffer processor's output buffer is empty
        using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor )
    */
    callbackResult = paContinue;
    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );

    
    /*
        If you need to byte swap or shift outputBuffer to convert it to
        host format, do it here.
    */

    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );


    if( callbackResult == paContinue )
    {
        /* nothing special to do */
    }
    else if( callbackResult == paAbort )
    {
        /* IMPLEMENT ME - finish playback immediately  */

        /* once finished, call the finished callback */
        if( stream->streamRepresentation.streamFinishedCallback != 0 )
            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
    }
    else
    {
        /* User callback has asked us to stop with paComplete or other non-zero value */

        /* IMPLEMENT ME - finish playback once currently queued audio has completed  */

        /* once finished, call the finished callback */
        if( stream->streamRepresentation.streamFinishedCallback != 0 )
            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
    }
}
示例#4
0
/*
 * I/O loop for callback interface
 */
static void *
sndioThread(void *arg)
{
	PaSndioStream *s = (PaSndioStream *)arg;
	PaStreamCallbackTimeInfo ti;
	unsigned char *data;
	unsigned todo, rblksz, wblksz;
	int n, result;
	
	rblksz = s->par.round * s->par.rchan * s->par.bps;
	wblksz = s->par.round * s->par.pchan * s->par.bps;
	
	DPR("sndioThread: mode = %x, round = %u, rblksz = %u, wblksz = %u\n",
	    s->mode, s->par.round, rblksz, wblksz);
	
	while (!s->stopped) {
		if (s->mode & SIO_REC) {
			todo = rblksz;
			data = s->rbuf;
			while (todo > 0) {
				n = sio_read(s->hdl, data, todo);
				if (n == 0) {
					DPR("sndioThread: sio_read failed\n");
					goto failed;
				}
				todo -= n;
				data += n;
			}
			s->rpos += s->par.round;
			ti.inputBufferAdcTime = 
			    (double)s->realpos / s->par.rate;
		}
		if (s->mode & SIO_PLAY) {
			ti.outputBufferDacTime =
			    (double)(s->realpos + s->par.bufsz) / s->par.rate;
		}
		ti.currentTime = s->realpos / (double)s->par.rate;
		PaUtil_BeginBufferProcessing(&s->bufproc, &ti, 0);
		if (s->mode & SIO_PLAY) {
			PaUtil_SetOutputFrameCount(&s->bufproc, s->par.round);
			PaUtil_SetInterleavedOutputChannels(&s->bufproc,
			    0, s->wbuf, s->par.pchan);
		}
		if (s->mode & SIO_REC) {
			PaUtil_SetInputFrameCount(&s->bufproc, s->par.round);
			PaUtil_SetInterleavedInputChannels(&s->bufproc,
			    0, s->rbuf, s->par.rchan);
		}
		result = paContinue;
		n = PaUtil_EndBufferProcessing(&s->bufproc, &result);
		if (n != s->par.round) {
			DPR("sndioThread: %d < %u frames, result = %d\n",
			    n, s->par.round, result);
		}
		if (result != paContinue) {
			break;
		}
		if (s->mode & SIO_PLAY) {
			n = sio_write(s->hdl, s->wbuf, wblksz);
			if (n < wblksz) {
				DPR("sndioThread: sio_write failed\n");
				goto failed;
			}
			s->wpos += s->par.round;
		}
	}
 failed:
	s->active = 0;
	DPR("sndioThread: done\n");
}
示例#5
0
static int setup_buffers( PaAlsaStream *stream, int frames_avail )
{
    int i;
    int capture_frames_avail = INT_MAX;
    int playback_frames_avail = INT_MAX;
    int common_frames_avail;

    if( stream->pcm_capture )
    {
        const snd_pcm_channel_area_t *capture_areas;
        const snd_pcm_channel_area_t *area;
        snd_pcm_uframes_t frames = frames_avail;

        /* I do not understand this code fragment yet, it is copied out of the
         * alsa-devel archives... */
        snd_pcm_mmap_begin( stream->pcm_capture, &capture_areas,
                            &stream->capture_offset, &frames);

        if( stream->capture_interleaved )
        {
            void *interleaved_capture_buffer;
            area = &capture_areas[0];
            interleaved_capture_buffer = ExtractAddress( area, stream->capture_offset );
            PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
                                                0, /* starting at channel 0 */
                                                interleaved_capture_buffer,
                                                0  /* default numInputChannels */
                                              );
        }
        else
        {
            /* noninterleaved */
            for( i = 0; i < stream->capture_channels; i++ )
            {
                void *noninterleaved_capture_buffer;
                area = &capture_areas[i];
                noninterleaved_capture_buffer = ExtractAddress( area, stream->capture_offset );
                PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor,
                                                      i,
                                                      noninterleaved_capture_buffer);
            }
        }

        capture_frames_avail = frames;
    }

    if( stream->pcm_playback )
    {
        const snd_pcm_channel_area_t *playback_areas;
        const snd_pcm_channel_area_t *area;
        snd_pcm_uframes_t frames = frames_avail;

        snd_pcm_mmap_begin( stream->pcm_playback, &playback_areas, 
                            &stream->playback_offset, &frames);

        if( stream->playback_interleaved )
        {
            void *interleaved_playback_buffer;
            area = &playback_areas[0];
            interleaved_playback_buffer = ExtractAddress( area, stream->playback_offset );
            PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
                                                 0, /* starting at channel 0 */
                                                 interleaved_playback_buffer,
                                                 0  /* default numInputChannels */
                                               );
        }
        else
        {
            /* noninterleaved */
            for( i = 0; i < stream->playback_channels; i++ )
            {
                void *noninterleaved_playback_buffer;
                area = &playback_areas[i];
                noninterleaved_playback_buffer = ExtractAddress( area, stream->playback_offset );
                PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor,
                                                      i,
                                                      noninterleaved_playback_buffer);
            }
        }

        playback_frames_avail = frames;
    }


    common_frames_avail = MIN(capture_frames_avail, playback_frames_avail);
    common_frames_avail -= common_frames_avail % stream->frames_per_period;
    //PA_DEBUG(( "%d capture frames available\n", capture_frames_avail ));
    //PA_DEBUG(( "%d frames playback available\n", playback_frames_avail ));
    //PA_DEBUG(( "%d frames available\n", common_frames_avail ));

    if( stream->pcm_capture )
        PaUtil_SetInputFrameCount( &stream->bufferProcessor, common_frames_avail );

    if( stream->pcm_playback )
        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, common_frames_avail );

    return common_frames_avail;
}