[SCM] Audacity debian packaging branch, master, updated. upstream/1.3.6-9-gbdc3de1
freee at users.alioth.debian.org
freee at users.alioth.debian.org
Wed Jan 14 09:31:26 UTC 2009
The following commit has been merged in the master branch:
commit c879bce0cf237fb527569d27c51bb4dcc01f4185
Author: Free Ekanayaka <free at 64studio.com>
Date: Sun Jan 11 23:12:28 2009 +0000
Add pulseaudio patch (thanks to David Henningsson)
diff --git a/debian/patches/pulseaudio.patch b/debian/patches/pulseaudio.patch
new file mode 100644
index 0000000..8bc0132
--- /dev/null
+++ b/debian/patches/pulseaudio.patch
@@ -0,0 +1,361 @@
+--- audacity-1.3.5/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c 2007-09-12 19:39:48.000000000 +0200
++++ audacity-1.3.5/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c 2008-11-09 04:13:07.000000000 +0100
+@@ -6,6 +6,7 @@
+ *
+ * Copyright (c) 2002 Joshua Haberman <joshua at haberman.com>
+ * Copyright (c) 2005-2007 Arve Knudsen <aknuds-1 at broadpark.no>
++ * Copyright (c) 2008 Kevin Kofler <kevin.kofler at 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; */ /* This above was commented out by David Henningsson, for Audacity - users need to be able to tweak latency themselves */
++
+ assert( framesPerHostBuffer > 0 );
+ {
+ snd_pcm_uframes_t min = 0, max = 0;
+@@ -1831,7 +1837,7 @@
+ 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;
+@@ -2059,9 +2065,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 +2398,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 +2409,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 +2419,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 +2575,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 +2583,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 +2650,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 +3030,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 +3056,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:
--
Audacity debian packaging
More information about the pkg-multimedia-commits
mailing list