Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALSA: Free global configuration tree after each snd_ctl_close and snd… #448

Merged
merged 1 commit into from
Dec 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 58 additions & 6 deletions RtAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7897,13 +7897,15 @@ void RtApiAlsa :: probeDevices( void )
deviceID_prettyName.push_back({"default", "Default ALSA Device"});
defaultDeviceName = deviceID_prettyName[0].second;
snd_ctl_close( handle );
snd_config_update_free_global();
}

// Add the Pulse interface if available.
result = snd_ctl_open( &handle, "pulse", 0 );
if (result == 0) {
deviceID_prettyName.push_back({"pulse", "PulseAudio Sound Server"});
snd_ctl_close( handle );
snd_config_update_free_global();
}

// Count cards and devices and get ascii identifiers.
Expand Down Expand Up @@ -7966,8 +7968,10 @@ void RtApiAlsa :: probeDevices( void )
defaultDeviceName = name;
}
nextcard:
if ( handle )
if ( handle ) {
snd_ctl_close( handle );
snd_config_update_free_global();
}
snd_card_next( &card );
}

Expand Down Expand Up @@ -8066,6 +8070,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
result = snd_pcm_hw_params_any( phandle, params );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
Expand All @@ -8077,13 +8082,15 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
result = snd_pcm_hw_params_get_channels_max( params, &value );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
goto captureProbe;
}
info.outputChannels = value;
snd_pcm_close( phandle );
snd_config_update_free_global();

captureProbe:
stream = SND_PCM_STREAM_CAPTURE;
Expand All @@ -8102,6 +8109,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
result = snd_pcm_hw_params_any( phandle, params );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
Expand All @@ -8112,6 +8120,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
result = snd_pcm_hw_params_get_channels_max( params, &value );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
Expand All @@ -8120,6 +8129,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
}
info.inputChannels = value;
snd_pcm_close( phandle );
snd_config_update_free_global();

// If device opens for both playback and capture, we determine the channels.
if ( info.outputChannels > 0 && info.inputChannels > 0 )
Expand Down Expand Up @@ -8149,6 +8159,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
result = snd_pcm_hw_params_any( phandle, params );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
Expand All @@ -8167,6 +8178,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
}
if ( info.sampleRates.size() == 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: no supported sample rates found for device (" << name << ").";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
Expand Down Expand Up @@ -8198,6 +8210,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )
// Check that we have at least one supported format
if ( info.nativeFormats == 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str();
error( RTAUDIO_WARNING );
Expand All @@ -8206,6 +8219,7 @@ bool RtApiAlsa :: probeDeviceInfo( RtAudio::DeviceInfo& info, std::string name )

// Close the device and return
snd_pcm_close( phandle );
snd_config_update_free_global();
return true;
}

Expand Down Expand Up @@ -8256,6 +8270,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_any( phandle, hw_params );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand Down Expand Up @@ -8290,6 +8305,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig

if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand Down Expand Up @@ -8356,6 +8372,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig

// If we get here, no supported format was found.
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8364,6 +8381,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_set_format( phandle, hw_params, deviceFormat );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8377,6 +8395,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
stream_.doByteSwap[mode] = true;
else if (result < 0) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8387,6 +8406,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_set_rate_near( phandle, hw_params, (unsigned int*) &sampleRate, 0 );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8400,6 +8420,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
unsigned int deviceChannels = value;
if ( result < 0 || deviceChannels < channels + firstChannel ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8408,6 +8429,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_get_channels_min( hw_params, &value );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8420,6 +8442,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_set_channels( phandle, hw_params, deviceChannels );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8431,6 +8454,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_set_period_size_near( phandle, hw_params, &periodSize, &dir );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8445,6 +8469,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params_set_periods_near( phandle, hw_params, &periods, &dir );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8454,6 +8479,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
// MUST be the same in both directions!
if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ").";
errorText_ = errorStream_.str();
return FAILURE;
Expand All @@ -8465,6 +8491,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_hw_params( phandle, hw_params );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand Down Expand Up @@ -8496,6 +8523,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
result = snd_pcm_sw_params( phandle, sw_params );
if ( result < 0 ) {
snd_pcm_close( phandle );
snd_config_update_free_global();
errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
return FAILURE;
Expand Down Expand Up @@ -8647,18 +8675,32 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int deviceId, StreamMode mode, unsig
}
}

snd_config_update_free_global();
return SUCCESS;

error:
if ( apiInfo ) {
pthread_cond_destroy( &apiInfo->runnable_cv );
if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
bool pcm_closed = false;
if ( apiInfo->handles[0] ) {
snd_pcm_close( apiInfo->handles[0] );
pcm_closed = true;
}
if ( apiInfo->handles[1] ) {
snd_pcm_close( apiInfo->handles[1] );
pcm_closed = true;
}
if ( pcm_closed ) {
snd_config_update_free_global();
}
delete apiInfo;
stream_.apiHandle = 0;
}

if ( phandle) snd_pcm_close( phandle );
if ( phandle) {
snd_pcm_close( phandle );
snd_config_update_free_global();
}

for ( int i=0; i<2; i++ ) {
if ( stream_.userBuffer[i] ) {
Expand Down Expand Up @@ -8704,8 +8746,18 @@ void RtApiAlsa :: closeStream()

if ( apiInfo ) {
pthread_cond_destroy( &apiInfo->runnable_cv );
if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
bool pcm_closed = false;
if ( apiInfo->handles[0] ){
snd_pcm_close( apiInfo->handles[0] );
pcm_closed = true;
}
if ( apiInfo->handles[1] ){
snd_pcm_close( apiInfo->handles[1] );
pcm_closed = true;
}
if ( pcm_closed ) {
snd_config_update_free_global();
}
delete apiInfo;
stream_.apiHandle = 0;
}
Expand Down
Loading