Hello community, here is the log from the commit of package audacity for openSUSE:Factory checked in at Fri May 29 01:45:39 CEST 2009. -------- --- audacity/audacity.changes 2009-05-19 18:30:02.000000000 +0200 +++ audacity/audacity.changes 2009-05-28 14:28:54.000000000 +0200 @@ -1,0 +2,6 @@ +Thu May 21 23:00:52 CEST 2009 - cmorve69@yahoo.es + +- Got portaudio-non-mmap-alsa.patch and audiodevdefaults.patch from + Fedora to allow it to work with PulseAudio + +------------------------------------------------------------------- calling whatdependson for head-i586 New: ---- audacity-1.3.7-audiodevdefaults.patch audacity-1.3.7-portaudio-non-mmap-alsa.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ audacity.spec ++++++ --- /var/tmp/diff_new_pack.jx1724/_old 2009-05-29 01:44:47.000000000 +0200 +++ /var/tmp/diff_new_pack.jx1724/_new 2009-05-29 01:44:47.000000000 +0200 @@ -38,7 +38,7 @@ %endif Summary: A Free, Cross-Platform Digital Audio Editor Version: 1.3.7 -Release: 4 +Release: 5 License: GPL v2 or later Group: Productivity/Multimedia/Sound/Editors and Convertors BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -55,6 +55,8 @@ Patch8: %{name}-%{version}-wxGTK_with_stl.patch Patch9: %{name}-%{version}-modal-help-dialog.patch Patch10: %{name}-%{version}-desktop_file.patch +Patch11: %{name}-%{version}-portaudio-non-mmap-alsa.patch +Patch12: %{name}-%{version}-audiodevdefaults.patch %description Audacity is a program that manipulates digital audio wave forms. In @@ -91,6 +93,8 @@ %patch8 %patch9 %patch10 +%patch11 -p1 +%patch12 -p1 %build %{?suse_update_config:%{suse_update_config -f . lib-src/*/.}} @@ -143,6 +147,9 @@ %{_datadir}/mime/packages/audacity.xml %changelog +* Thu May 21 2009 cmorve69@yahoo.es +- Got portaudio-non-mmap-alsa.patch and audiodevdefaults.patch from + Fedora to allow it to work with PulseAudio * Tue May 19 2009 cmorve69@yahoo.es - Add alsa-devel BR to allow ALSA output * Mon May 11 2009 cmorve69@yahoo.es ++++++ audacity-1.3.7-audiodevdefaults.patch ++++++ diff -Nur audacity-src-1.3.7-orig/src/prefs/AudioIOPrefs.cpp audacity-src-1.3.7/src/prefs/AudioIOPrefs.cpp --- audacity-src-1.3.7-orig/src/prefs/AudioIOPrefs.cpp 2009-01-27 21:50:58.000000000 +0100 +++ audacity-src-1.3.7/src/prefs/AudioIOPrefs.cpp 2009-03-02 17:25:17.000000000 +0100 @@ -71,6 +71,25 @@ wxString Name; wxString Label; + mDefaultPlayDeviceName = gPrefs->Read(wxT("/AudioIO/PlaybackDevice"), wxT("")); + int playDeviceNum = -1; // use device name from gPrefs + if ( mDefaultPlayDeviceName == wxT("") ) { +#if USE_PORTAUDIO_V19 + playDeviceNum = Pa_GetDefaultOutputDevice(); +#else + playDeviceNum = Pa_GetDefaultOutputDeviceID(); +#endif + } + mDefaultRecDeviceName = gPrefs->Read(wxT("/AudioIO/RecordingDevice"), wxT("")); + int recDeviceNum = -1; // use device name from gPrefs + if ( mDefaultRecDeviceName == wxT("") ) { +#if USE_PORTAUDIO_V19 + recDeviceNum = Pa_GetDefaultInputDevice(); +#else + recDeviceNum = Pa_GetDefaultInputDeviceID(); +#endif + } + #if USE_PORTAUDIO_V19 int nDevices = Pa_GetDeviceCount(); #else @@ -85,10 +104,16 @@ if (info->maxOutputChannels > 0) { mmPlayNames.Add( Name ); mmPlayLabels.Add( Label ); + if ( playDeviceNum == j ) { + mDefaultPlayDeviceName = Name; + } } if (info->maxInputChannels > 0) { mmRecordNames.Add( Name ); mmRecordLabels.Add( Label ); + if ( recDeviceNum == j ) { + mDefaultRecDeviceName = Name; + } // if (info->maxInputChannels > numChannels) // numChannels = info->maxInputChannels; } @@ -121,7 +146,7 @@ S.StartMultiColumn(2, wxEXPAND); S.SetStretchyCol(1); mPlay = S.TieChoice( _("Device") + wxString(wxT(":")), wxT("PlaybackDevice"), - wxT(""), mmPlayNames, mmPlayLabels ); + mDefaultPlayDeviceName, mmPlayNames, mmPlayLabels ); S.AddPrompt( _("Using:") ); wxString ver = _("Portaudio v"); @@ -139,7 +164,7 @@ S.StartMultiColumn(2, wxEXPAND); S.SetStretchyCol(1); mRec = S.TieChoice( _("Device") + wxString(wxT(":")), wxT("RecordingDevice"), - wxT(""), mmRecordNames, mmRecordLabels ); + mDefaultRecDeviceName, mmRecordNames, mmRecordLabels ); S.TieChoice( _("Channels") + wxString(wxT(":")), wxT("RecordChannels"), 2, mmChannelNames, mmChannelLabels ); S.EndMultiColumn(); diff -Nur audacity-src-1.3.7-orig/src/prefs/AudioIOPrefs.h audacity-src-1.3.7/src/prefs/AudioIOPrefs.h --- audacity-src-1.3.7-orig/src/prefs/AudioIOPrefs.h 2009-01-27 21:50:58.000000000 +0100 +++ audacity-src-1.3.7/src/prefs/AudioIOPrefs.h 2009-03-02 17:25:16.000000000 +0100 @@ -48,6 +48,9 @@ wxChoice *mPlay; wxChoice *mRec; + + wxString mDefaultPlayDeviceName; + wxString mDefaultRecDeviceName; }; #endif ++++++ audacity-1.3.7-portaudio-non-mmap-alsa.patch ++++++ diff -Nur audacity-src-1.3.7-orig/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c audacity-src-1.3.7/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c --- audacity-src-1.3.7-orig/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c 2009-01-27 21:51:40.000000000 +0100 +++ audacity-src-1.3.7/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c 2009-02-02 19:08:22.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: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org