Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 195819 Details for
Bug 275490
media-sound/audacity: Pulseaudio support for Audacity-1.3.7
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Adds Pulseaudio support to Audacity
audacity-1.3.6-pulseaudio.patch (text/plain), 13.77 KB, created by
Reto Gantenbein (ganto)
on 2009-06-26 14:32:30 UTC
(
hide
)
Description:
Adds Pulseaudio support to Audacity
Filename:
MIME Type:
Creator:
Reto Gantenbein (ganto)
Created:
2009-06-26 14:32:30 UTC
Size:
13.77 KB
patch
obsolete
>Patch taken from https://bugzilla.redhat.com/show_bug.cgi?id=450450 > >upstream status unknown > >--- 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@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; */ /* 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:
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 275490
:
195818
| 195819 |
195918