123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- diff -ur portaudio/src/hostapi/alsa/pa_linux_alsa.c portaudio-pulseaudio/src/hostapi/alsa/pa_linux_alsa.c
- --- portaudio/src/hostapi/alsa/pa_linux_alsa.c 2007-09-12 19:39:48.000000000 +0200
- +++ portaudio-pulseaudio/src/hostapi/alsa/pa_linux_alsa.c 2008-12-08 19:30:20.000000000 +0100
- @@ -6,6 +6,7 @@
- *
- * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com>
- * Copyright (c) 2005-2007 Arve Knudsen <aknuds-1@broadpark.no>
- + * Copyright (c) 2008 Kevin Kofler <kevin.kofler@chello.at>
- *
- * Based on the Open Source API proposed by Ross Bencina
- * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
- @@ -118,6 +119,8 @@
- unsigned long framesPerBuffer;
- int numUserChannels, numHostChannels;
- int userInterleaved, hostInterleaved;
- + int canMmap;
- + void *nonMmapBuffer;
- PaDeviceIndex device; /* Keep the device index */
-
- snd_pcm_t *pcm;
- @@ -321,7 +324,7 @@
- * and a suitable result returned. The device is closed before returning.
- */
- static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking,
- - PaAlsaDeviceInfo* devInfo, int* canMmap )
- + PaAlsaDeviceInfo* devInfo )
- {
- PaError result = paNoError;
- snd_pcm_hw_params_t *hwParams;
- @@ -354,9 +357,6 @@
- snd_pcm_hw_params_alloca( &hwParams );
- snd_pcm_hw_params_any( pcm, hwParams );
-
- - *canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_INTERLEAVED ) >= 0 ||
- - snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_NONINTERLEAVED ) >= 0;
- -
- if( defaultSr >= 0 )
- {
- /* Could be that the device opened in one mode supports samplerates that the other mode wont have,
- @@ -566,7 +566,6 @@
- PaError result = 0;
- PaDeviceInfo *baseDeviceInfo = &devInfo->baseDeviceInfo;
- snd_pcm_t *pcm;
- - int canMmap = -1;
- PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep;
-
- /* Zero fields */
- @@ -580,8 +579,7 @@
- OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 )
- >= 0 )
- {
- - if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_In, blocking, devInfo,
- - &canMmap ) != paNoError )
- + if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_In, blocking, devInfo ) != paNoError )
- {
- /* Error */
- PA_DEBUG(("%s: Failed groping %s for capture\n", __FUNCTION__, deviceName->alsaName));
- @@ -594,8 +592,7 @@
- OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 )
- >= 0 )
- {
- - if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_Out, blocking, devInfo,
- - &canMmap ) != paNoError )
- + if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_Out, blocking, devInfo ) != paNoError )
- {
- /* Error */
- PA_DEBUG(("%s: Failed groping %s for playback\n", __FUNCTION__, deviceName->alsaName));
- @@ -603,12 +600,6 @@
- }
- }
-
- - if( 0 == canMmap )
- - {
- - PA_DEBUG(("%s: Device %s doesn't support mmap\n", __FUNCTION__, deviceName->alsaName));
- - goto end;
- - }
- -
- baseDeviceInfo->structVersion = 2;
- baseDeviceInfo->hostApi = alsaApi->hostApiIndex;
- baseDeviceInfo->name = deviceName->name;
- @@ -1197,6 +1188,8 @@
- self->hostInterleaved = self->userInterleaved = !(userSampleFormat & paNonInterleaved);
- self->numUserChannels = params->channelCount;
- self->streamDir = streamDir;
- + self->canMmap = 0;
- + self->nonMmapBuffer = NULL;
-
- if( !callbackMode && !self->userInterleaved )
- {
- @@ -1239,6 +1232,7 @@
-
- PaError result = paNoError;
- snd_pcm_access_t accessMode, alternateAccessMode;
- + snd_pcm_access_t rwAccessMode, alternateRwAccessMode;
- int dir = 0;
- snd_pcm_t *pcm = self->pcm;
- double sr = *sampleRate;
- @@ -1258,32 +1252,40 @@
- if( self->userInterleaved )
- {
- accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
- + rwAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
- alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
- + alternateRwAccessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED;
- }
- else
- {
- accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
- + rwAccessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED;
- alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
- + alternateRwAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED;
- }
- /* If requested access mode fails, try alternate mode */
- + self->canMmap = 1;
- if( snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 )
- {
- - int err = 0;
- - if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0)
- + if( snd_pcm_hw_params_set_access( pcm, hwParams, rwAccessMode ) >= 0 )
- + self->canMmap = 0;
- + else
- {
- - result = paUnanticipatedHostError;
- - if( -EINVAL == err )
- + if( snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode ) < 0 )
- {
- - PaUtil_SetLastHostErrorInfo( paALSA, err, "PA ALSA requires that a device supports mmap access" );
- - }
- - else
- - {
- - PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );
- + int err = 0;
- + if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateRwAccessMode )) >= 0)
- + self->canMmap = 0;
- + else
- + {
- + result = paUnanticipatedHostError;
- + PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );
- + goto error;
- + }
- }
- - goto error;
- + /* Flip mode */
- + self->hostInterleaved = !self->userInterleaved;
- }
- - /* Flip mode */
- - self->hostInterleaved = !self->userInterleaved;
- }
-
- ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError );
- @@ -1361,7 +1363,7 @@
-
- ENSURE_( snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
- ENSURE_( snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError );
- - ENSURE_( snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError );
- + ENSURE_( snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_ENABLE ), paUnanticipatedHostError );
-
- /* Set the parameters! */
- ENSURE_( snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError );
- @@ -1589,6 +1591,10 @@
- }
- }
-
- + /* non-mmap mode needs a reasonably-sized buffer or it'll stutter */
- + if( !self->canMmap && framesPerHostBuffer < 2048 )
- + framesPerHostBuffer = 2048;
- +
- assert( framesPerHostBuffer > 0 );
- {
- snd_pcm_uframes_t min = 0, max = 0;
- @@ -1831,12 +1837,13 @@
- PA_UNLESS( framesPerHostBuffer != 0, paInternalError );
- self->maxFramesPerHostBuffer = framesPerHostBuffer;
-
- - if( !accurate )
- + if( !self->playback.canMmap || !accurate )
- {
- /* Don't know the exact size per host buffer */
- *hostBufferSizeMode = paUtilBoundedHostBufferSize;
- /* Raise upper bound */
- - ++self->maxFramesPerHostBuffer;
- + if( !accurate )
- + ++self->maxFramesPerHostBuffer;
- }
-
- error:
- @@ -2059,9 +2066,11 @@
- {
- /* Buffer isn't primed, so prepare and silence */
- ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
- - SilenceBuffer( stream );
- + if( stream->playback.canMmap )
- + SilenceBuffer( stream );
- }
- - ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
- + if( stream->playback.canMmap )
- + ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
- }
- else
- ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
- @@ -2390,6 +2399,7 @@
- snd_pcm_status_t *st;
- PaTime now = PaUtil_GetTime();
- snd_timestamp_t t;
- + int errplayback = 0, errcapture = 0;
-
- snd_pcm_status_alloca( &st );
-
- @@ -2400,6 +2410,7 @@
- {
- snd_pcm_status_get_trigger_tstamp( st, &t );
- self->underrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000);
- + errplayback = snd_pcm_recover( self->playback.pcm, -EPIPE, 0 );
- }
- }
- if( self->capture.pcm )
- @@ -2409,10 +2420,12 @@
- {
- snd_pcm_status_get_trigger_tstamp( st, &t );
- self->overrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000);
- + errcapture = snd_pcm_recover( self->capture.pcm, -EPIPE, 0 );
- }
- }
-
- - PA_ENSURE( AlsaRestart( self ) );
- + if( errplayback || errcapture )
- + PA_ENSURE( AlsaRestart( self ) );
-
- end:
- return result;
- @@ -2563,7 +2576,7 @@
- static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self, unsigned long numFrames, int *xrun )
- {
- PaError result = paNoError;
- - int res;
- + int res = 0;
-
- /* @concern FullDuplex It is possible that only one direction is marked ready after polling, and processed
- * afterwards
- @@ -2571,7 +2584,34 @@
- if( !self->ready )
- goto end;
-
- - res = snd_pcm_mmap_commit( self->pcm, self->offset, numFrames );
- + if( !self->canMmap && StreamDirection_Out == self->streamDir )
- + {
- + /* Play sound */
- + if( self->hostInterleaved )
- + res = snd_pcm_writei( self->pcm, self->nonMmapBuffer, numFrames );
- + else
- + {
- + void *bufs[self->numHostChannels];
- + int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
- + unsigned char *buffer = self->nonMmapBuffer;
- + int i;
- + for( i = 0; i < self->numHostChannels; ++i )
- + {
- + bufs[i] = buffer;
- + buffer += bufsize;
- + }
- + res = snd_pcm_writen( self->pcm, bufs, numFrames );
- + }
- + }
- +
- + if( self->canMmap )
- + res = snd_pcm_mmap_commit( self->pcm, self->offset, numFrames );
- + else
- + {
- + free( self->nonMmapBuffer );
- + self->nonMmapBuffer = NULL;
- + }
- +
- if( res == -EPIPE || res == -ESTRPIPE )
- {
- *xrun = 1;
- @@ -2611,7 +2651,7 @@
- if( self->hostInterleaved )
- {
- int swidth = snd_pcm_format_size( self->nativeFormat, 1 );
- - unsigned char *buffer = ExtractAddress( self->channelAreas, self->offset );
- + unsigned char *buffer = self->canMmap ? ExtractAddress( self->channelAreas, self->offset ) : self->nonMmapBuffer;
-
- /* Start after the last user channel */
- p = buffer + self->numUserChannels * swidth;
- @@ -2991,13 +3031,23 @@
- goto end;
- }
-
- - ENSURE_( snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError );
- + if( self->canMmap )
- + {
- + ENSURE_( snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError );
- + /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */
- + self->channelAreas = (snd_pcm_channel_area_t *)areas;
- + }
- + else
- + {
- + free( self->nonMmapBuffer );
- + self->nonMmapBuffer = calloc( self->numHostChannels, snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 ) );
- + }
-
- if( self->hostInterleaved )
- {
- int swidth = snd_pcm_format_size( self->nativeFormat, 1 );
-
- - p = buffer = ExtractAddress( areas, self->offset );
- + p = buffer = self->canMmap ? ExtractAddress( areas, self->offset ) : self->nonMmapBuffer;
- for( i = 0; i < self->numUserChannels; ++i )
- {
- /* We're setting the channels up to userChannels, but the stride will be hostChannels samples */
- @@ -3007,16 +3057,52 @@
- }
- else
- {
- - for( i = 0; i < self->numUserChannels; ++i )
- + if( self->canMmap )
- + for( i = 0; i < self->numUserChannels; ++i )
- + {
- + area = areas + i;
- + buffer = ExtractAddress( area, self->offset );
- + setChannel( bp, i, buffer, 1 );
- + }
- + else
- {
- - area = areas + i;
- - buffer = ExtractAddress( area, self->offset );
- - setChannel( bp, i, buffer, 1 );
- + int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
- + buffer = self->nonMmapBuffer;
- + for( i = 0; i < self->numUserChannels; ++i )
- + {
- + setChannel( bp, i, buffer, 1 );
- + buffer += bufsize;
- + }
- }
- }
-
- - /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */
- - self->channelAreas = (snd_pcm_channel_area_t *)areas;
- + if( !self->canMmap && StreamDirection_In == self->streamDir )
- + {
- + /* Read sound */
- + int res;
- + if( self->hostInterleaved )
- + res = snd_pcm_readi( self->pcm, self->nonMmapBuffer, *numFrames );
- + else
- + {
- + void *bufs[self->numHostChannels];
- + int bufsize = snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
- + unsigned char *buffer = self->nonMmapBuffer;
- + int i;
- + for( i = 0; i < self->numHostChannels; ++i )
- + {
- + bufs[i] = buffer;
- + buffer += bufsize;
- + }
- + res = snd_pcm_readn( self->pcm, bufs, *numFrames );
- + }
- + if( res == -EPIPE || res == -ESTRPIPE )
- + {
- + *xrun = 1;
- + *numFrames = 0;
- + free( self->nonMmapBuffer );
- + self->nonMmapBuffer = NULL;
- + }
- + }
-
- end:
- error:
- diff -ur portaudio/src/os/unix/pa_unix_hostapis.c portaudio-pulseaudio/src/os/unix/pa_unix_hostapis.c
- --- portaudio/src/os/unix/pa_unix_hostapis.c 2006-08-26 10:27:53.000000000 +0200
- +++ portaudio-pulseaudio/src/os/unix/pa_unix_hostapis.c 2008-11-09 04:51:04.000000000 +0100
- @@ -75,4 +75,8 @@
- 0 /* NULL terminated array */
- };
-
- +#if defined(PA_USE_OSS) && defined(PA_USE_ALSA)
- +int paDefaultHostApiIndex = 1;
- +#else
- int paDefaultHostApiIndex = 0;
- +#endif
|