From 2e416ee0095f1bf608f849f156d564e0f45fb8ab Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 2 Feb 2004 12:18:59 +0000 Subject: merged in version_0_37_1test6 svn path=/trunk/; revision=1305 --- pd/portaudio/pa_linux_alsa/callback_thread.c | 374 --------------------------- 1 file changed, 374 deletions(-) delete mode 100644 pd/portaudio/pa_linux_alsa/callback_thread.c (limited to 'pd/portaudio/pa_linux_alsa/callback_thread.c') diff --git a/pd/portaudio/pa_linux_alsa/callback_thread.c b/pd/portaudio/pa_linux_alsa/callback_thread.c deleted file mode 100644 index 483557b6..00000000 --- a/pd/portaudio/pa_linux_alsa/callback_thread.c +++ /dev/null @@ -1,374 +0,0 @@ - -#include -#include -#include /* abs() */ - -#include - -#include "pa_linux_alsa.h" - -#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) - -static int wait( PaAlsaStream *stream ) -{ - int need_capture; - int need_playback; - int capture_avail = INT_MAX; - int playback_avail = INT_MAX; - int common_avail; - - if( stream->pcm_capture ) - need_capture = 1; - else - need_capture = 0; - - if( stream->pcm_playback ) - need_playback = 1; - else - need_playback = 0; - - while( need_capture || need_playback ) - { - int playback_pfd_offset=0; - int total_fds = 0; - - /* if the main thread has requested that we stop, do so now */ - pthread_testcancel(); - - /*printf("still polling...\n"); - if( need_capture ) - printf("need capture.\n"); - if( need_playback ) - printf("need playback.\n"); */ - - /* get the fds, packing all applicable fds into a single array, - * so we can check them all with a single poll() call */ - - if( need_capture ) - { - snd_pcm_poll_descriptors( stream->pcm_capture, stream->pfds, - stream->capture_nfds ); - total_fds += stream->capture_nfds; - } - - if( need_playback ) - { - playback_pfd_offset = total_fds; - snd_pcm_poll_descriptors( stream->pcm_playback, - stream->pfds + playback_pfd_offset, - stream->playback_nfds ); - total_fds += stream->playback_nfds; - } - - /* now poll on the combination of playback and capture fds. - * TODO: handle interrupt and/or failure */ - poll( stream->pfds, total_fds, 1000 ); - - /* check the return status of our pfds */ - if( need_capture ) - { - short revents; - snd_pcm_poll_descriptors_revents( stream->pcm_capture, stream->pfds, - stream->capture_nfds, &revents ); - if( revents == POLLIN ) - need_capture = 0; - } - - if( need_playback ) - { - short revents; - snd_pcm_poll_descriptors_revents( stream->pcm_playback, - stream->pfds + playback_pfd_offset, - stream->playback_nfds, &revents ); - //if( revents & POLLOUT ) - //if( revents & POLLERR ) - // printf("polling error!"); - if( revents == POLLOUT ) - need_playback = 0; - } - } - - /* we have now established that there are buffers ready to be - * operated on. Now determine how many frames are available. */ - if( stream->pcm_capture ) - capture_avail = snd_pcm_avail_update( stream->pcm_capture ); - - if( stream->pcm_playback ) - playback_avail = snd_pcm_avail_update( stream->pcm_playback ); - - common_avail = MIN(capture_avail, playback_avail); - common_avail -= common_avail % stream->frames_per_period; - - return common_avail; -} - -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 = area->addr + - (area->first + area->step * stream->capture_offset) / 8; - PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, - 0, /* starting at channel 0 */ - interleaved_capture_buffer, - 0 /* default numInputChannels */ - ); - } - else - { - /* noninterleaved */ - void *noninterleaved_capture_buffers[1000]; - for( i = 0; i < stream->capture_channels; i++ ) - { - area = &capture_areas[i]; - noninterleaved_capture_buffers[i] = area->addr + - (area->first + area->step * stream->capture_offset) / 8; - PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor, - i, - noninterleaved_capture_buffers[i]); - } - } - - 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; - - /* I do not understand this code fragment yet, it is copied out of the - * alsa-devel archives... */ - 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 = area->addr + - (area->first + area->step * stream->playback_offset) / 8; - PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, - 0, /* starting at channel 0 */ - interleaved_playback_buffer, - 0 /* default numInputChannels */ - ); - } - else - { - /* noninterleaved */ - void *noninterleaved_playback_buffers[1000]; - for( i = 0; i < stream->playback_channels; i++ ) - { - area = &playback_areas[i]; - noninterleaved_playback_buffers[i] = area->addr + - (area->first + area->step * stream->playback_offset) / 8; - PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor, - i, - noninterleaved_playback_buffers[i]); - } - } - - playback_frames_avail = frames; - } - - - common_frames_avail = MIN(capture_frames_avail, playback_frames_avail); - common_frames_avail -= common_frames_avail % stream->frames_per_period; - //printf( "%d capture frames available\n", capture_frames_avail ); - //printf( "%d frames playback available\n", playback_frames_avail ); - //printf( "%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; -} - -void *CallbackThread( void *userData ) -{ - PaAlsaStream *stream = (PaAlsaStream*)userData; - - if( stream->pcm_capture ) - snd_pcm_start( stream->pcm_capture ); - if( stream->pcm_playback ) - snd_pcm_start( stream->pcm_playback ); - - while(1) - { - int frames_avail; - int frames_got; - - PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */ - int callbackResult; - int framesProcessed; - - pthread_testcancel(); - { - /* calculate time info */ - snd_timestamp_t capture_timestamp; - snd_timestamp_t playback_timestamp; - snd_pcm_status_t *capture_status; - snd_pcm_status_t *playback_status; - snd_pcm_status_alloca( &capture_status ); - snd_pcm_status_alloca( &playback_status ); - - if( stream->pcm_capture ) - { - snd_pcm_status( stream->pcm_capture, capture_status ); - snd_pcm_status_get_tstamp( capture_status, &capture_timestamp ); - } - if( stream->pcm_playback ) - { - snd_pcm_status( stream->pcm_playback, playback_status ); - snd_pcm_status_get_tstamp( playback_status, &playback_timestamp ); - } - - /* Hmm, we potentially have both a playback and a capture timestamp. - * Hopefully they are the same... */ - if( stream->pcm_capture && stream->pcm_playback ) - { - float capture_time = capture_timestamp.tv_sec + - ((float)capture_timestamp.tv_usec/1000000); - float playback_time= playback_timestamp.tv_sec + - ((float)playback_timestamp.tv_usec/1000000); - if( fabsf(capture_time-playback_time) > 0.01 ) - printf("Capture time and playback time differ by %f\n", fabsf(capture_time-playback_time)); - timeInfo.currentTime = capture_time; - } - else if( stream->pcm_playback ) - { - timeInfo.currentTime = playback_timestamp.tv_sec + - ((float)playback_timestamp.tv_usec/1000000); - } - else - { - timeInfo.currentTime = capture_timestamp.tv_sec + - ((float)capture_timestamp.tv_usec/1000000); - } - - if( stream->pcm_capture ) - { - snd_pcm_sframes_t capture_delay = snd_pcm_status_get_delay( capture_status ); - timeInfo.inputBufferAdcTime = timeInfo.currentTime - - (float)capture_delay / stream->streamRepresentation.streamInfo.sampleRate; - } - - if( stream->pcm_playback ) - { - snd_pcm_sframes_t playback_delay = snd_pcm_status_get_delay( playback_status ); - timeInfo.outputBufferDacTime = timeInfo.currentTime + - (float)playback_delay / stream->streamRepresentation.streamInfo.sampleRate; - } - } - - - /* - IMPLEMENT ME: - - handle buffer slips - */ - - /* - depending on whether the host buffers are interleaved, non-interleaved - or a mixture, you will want to call PaUtil_ProcessInterleavedBuffers(), - PaUtil_ProcessNonInterleavedBuffers() or PaUtil_ProcessBuffers() here. - */ - - frames_avail = wait( stream ); - //printf( "%d frames available\n", frames_avail ); - - /* Now we know the soundcard is ready to produce/receive at least - * one period. We just need to get the buffers for the client - * to read/write. */ - PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo ); - - frames_got = setup_buffers( stream, frames_avail ); - - if( frames_avail == frames_got ) - ;//printf("good, they were both %d\n", frames_avail ); - else - printf("damn, they were different: avail: %d, got: %d\n", frames_avail, frames_got ); - - /* this calls the callback */ - - PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); - - framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, - &callbackResult ); - - PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); - - /* inform ALSA how many frames we wrote */ - - if( stream->pcm_capture ) - snd_pcm_mmap_commit( stream->pcm_capture, stream->capture_offset, frames_avail ); - - if( stream->pcm_playback ) - snd_pcm_mmap_commit( stream->pcm_playback, stream->playback_offset, frames_avail ); - - - /* - If you need to byte swap outputBuffer, you can do it here using - routines in pa_byteswappers.h - */ - - if( callbackResult == paContinue ) - { - /* nothing special to do */ - } - else if( callbackResult == paAbort ) - { - stream->callback_finished = 1; - - if( stream->pcm_capture ) - { - snd_pcm_drop( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_drop( stream->pcm_playback ); - } - pthread_exit(NULL); - } - else - { - stream->callback_finished = 1; - - if( stream->pcm_capture ) - { - snd_pcm_drain( stream->pcm_capture ); - } - - if( stream->pcm_playback ) - { - snd_pcm_drain( stream->pcm_playback ); - } - pthread_exit(NULL); - } - - } -} - -- cgit v1.2.1