Skip to content

Commit

Permalink
Improve UX in error messages (jamulussoftware#1568) (jamulussoftware#…
Browse files Browse the repository at this point in the history
…1732)

* Rephrase error messages

Some error messages were either short or too long. UX can be improved in quite some messages.

Co-authored-by: Jonathan <[email protected]>

* Apply suggestions

* Apply suggestions from code review

Co-authored-by: mulyaj <[email protected]>

* Fix syntax error

* Add APP_NAME

* Apply Clang-Format

* Apply clang-format on OS sound code

* Unify writing

Co-authored-by: Martin Passing <[email protected]>

* Fix grammar

Co-authored-by: Martin Passing <[email protected]>

* Change JACK to JACK server

Co-authored-by: Martin Passing <[email protected]>

* Update linux/sound.cpp

* Apply suggestions from code review

Co-authored-by: Jonathan <[email protected]>

* Apply suggestions from code review

* Apply Clang-Format

Co-authored-by: Jonathan <[email protected]>
Co-authored-by: mulyaj <[email protected]>
Co-authored-by: Martin Passing <[email protected]>
  • Loading branch information
4 people authored Jun 21, 2021
1 parent 40c794d commit 40d4b47
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 112 deletions.
43 changes: 21 additions & 22 deletions linux/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,15 @@ void CSound::OpenJack ( const bool bNoAutoJackConnect, const char* jackClientNam
serverName = "default";
}
qInfo() << qUtf8Printable (
QString ( "Connecting to jack \"%1\" instance (use the JACK_DEFAULT_SERVER environment variable to change this)." ).arg ( serverName ) );
QString ( "Connecting to JACK \"%1\" instance (use the JACK_DEFAULT_SERVER environment variable to change this)." ).arg ( serverName ) );

// try to become a client of the JACK server
pJackClient = jack_client_open ( jackClientName, JackNullOption, &JackStatus );

if ( pJackClient == nullptr )
{
throw CGenErr ( tr ( "The Jack server is not running. This software "
"requires a Jack server to run. Normally if the Jack server is "
"not running this software will automatically start the Jack server. "
"It seems that this auto start has not worked. Try to start the Jack "
"server manually." ) );
throw CGenErr ( tr ( "JACK couldn't be started automatically. "
"Please start JACK manually and check for error messages." ) );
}

// tell the JACK server to call "process()" whenever
Expand All @@ -64,16 +61,10 @@ void CSound::OpenJack ( const bool bNoAutoJackConnect, const char* jackClientNam
// check sample rate, if not correct, just fire error
if ( jack_get_sample_rate ( pJackClient ) != SYSTEM_SAMPLE_RATE_HZ )
{
throw CGenErr ( tr ( "The Jack server sample rate is different from "
"the required one. The required sample rate is:" ) +
" <b>" + QString().setNum ( SYSTEM_SAMPLE_RATE_HZ ) + " Hz</b>. " +
tr ( "You can "
"use a tool like <i><a href=\"https://qjackctl.sourceforge.io\">QJackCtl</a></i> "
"to adjust the Jack server sample rate." ) +
"<br>" +
tr ( "Make sure to set the "
"Frames/Period to a low value like " ) +
QString().setNum ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ) + tr ( " to achieve a low delay." ) );
throw CGenErr ( QString ( tr ( "JACK isn't running at a sample rate of <b>%1 Hz</b>. Please use "
"a tool like <i><a href=\"https://qjackctl.sourceforge.io\">QjackCtl</a></i> to set the "
"the JACK sample rate to %1 Hz." ) )
.arg ( SYSTEM_SAMPLE_RATE_HZ ) );
}

// create four ports (two for input, two for output -> stereo)
Expand All @@ -87,7 +78,10 @@ void CSound::OpenJack ( const bool bNoAutoJackConnect, const char* jackClientNam

if ( ( input_port_left == nullptr ) || ( input_port_right == nullptr ) || ( output_port_left == nullptr ) || ( output_port_right == nullptr ) )
{
throw CGenErr ( tr ( "The Jack port registering failed." ) );
throw CGenErr ( QString ( tr ( "The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. "
"Afterwards check if another program at a sample rate of %2 Hz can connect to JACK." ) )
.arg ( APP_NAME )
.arg ( SYSTEM_SAMPLE_RATE_HZ ) );
}

// optional MIDI initialization
Expand All @@ -97,7 +91,9 @@ void CSound::OpenJack ( const bool bNoAutoJackConnect, const char* jackClientNam

if ( input_port_midi == nullptr )
{
throw CGenErr ( tr ( "The Jack port registering failed." ) );
throw CGenErr ( QString ( tr ( "The JACK port registration failed. This is probably an error with JACK. Please stop %1 and JACK. "
"Afterwards, check if another MIDI program can connect to JACK." ) )
.arg ( APP_NAME ) );
}
}
else
Expand All @@ -108,7 +104,8 @@ void CSound::OpenJack ( const bool bNoAutoJackConnect, const char* jackClientNam
// tell the JACK server that we are ready to roll
if ( jack_activate ( pJackClient ) )
{
throw CGenErr ( tr ( "Cannot activate the Jack client." ) );
throw CGenErr ( QString ( tr ( "Can't activate the JACK client. This is probably an error with JACK. Please check the JACK output." ) )
.arg ( APP_NAME ) );
}

if ( !bNoAutoJackConnect )
Expand Down Expand Up @@ -210,9 +207,11 @@ int CSound::Init ( const int /* iNewPrefMonoBufferSize */ )
// without a Jack server, Jamulus makes no sense to run, throw an error message
if ( bJackWasShutDown )
{
throw CGenErr ( tr ( "The Jack server was shut down. This software "
"requires a Jack server to run. Try to restart the software to "
"solve the issue." ) );
throw CGenErr ( QString ( tr ( "JACK was shut down. %1 "
"requires JACK to run. Please restart %1 to "
"start JACK again. "
"the JACK output." ) )
.arg ( APP_NAME ) );
}

// get actual buffer size
Expand Down
42 changes: 21 additions & 21 deletions mac/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,17 @@ void CSound::GetAvailableInOutDevices()

if ( AudioObjectGetPropertyData ( kAudioObjectSystemObject, &stPropertyAddress, 0, NULL, &iPropertySize, &audioInputDevice[lNumDevs] ) )
{
throw CGenErr ( tr ( "CoreAudio input AudioHardwareGetProperty call failed. "
"It seems that no sound card is available in the system." ) );
throw CGenErr ( tr ( "No sound card is available in your system. "
"CoreAudio input AudioHardwareGetProperty call failed." ) );
}

iPropertySize = sizeof ( AudioDeviceID );
stPropertyAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;

if ( AudioObjectGetPropertyData ( kAudioObjectSystemObject, &stPropertyAddress, 0, NULL, &iPropertySize, &audioOutputDevice[lNumDevs] ) )
{
throw CGenErr ( tr ( "CoreAudio output AudioHardwareGetProperty call failed. "
"It seems that no sound card is available in the system." ) );
throw CGenErr ( tr ( "No sound card is available in the system. "
"CoreAudio output AudioHardwareGetProperty call failed." ) );
}

lNumDevs++; // next device
Expand Down Expand Up @@ -281,7 +281,7 @@ QString CSound::LoadAndInitializeDriver ( QString strDriverName, bool )
// if the selected driver was not found, return an error message
if ( iDriverIdx == INVALID_INDEX )
{
return tr ( "The current selected audio device is no longer present in the system." );
return tr ( "The currently selected audio device is no longer present. Please check your audio device." );
}

// check device capabilities if it fulfills our requirements
Expand Down Expand Up @@ -382,7 +382,7 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )

if ( AudioObjectGetPropertyData ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &inputSampleRate ) )
{
return QString ( tr ( "The audio input device is no longer available." ) );
return QString ( tr ( "The audio input device is no longer available. Please check if your input device is connected correctly." ) );
}

if ( inputSampleRate != fSystemSampleRate )
Expand All @@ -391,10 +391,9 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
if ( AudioObjectSetPropertyData ( audioInputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, sizeof ( Float64 ), &fSystemSampleRate ) !=
noErr )
{
return QString ( tr ( "Current system audio input device sample "
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
"Applications->Utilities and try to set a sample rate of %2 Hz." ) )
.arg ( static_cast<int> ( inputSampleRate ) )
return QString ( tr ( "The sample rate on the current input device isn't %1 Hz and is therefore incompatible. "
"Please select another device or try setting the sample rate to %1 Hz "
"manually via Audio-MIDI-Setup (in Applications->Utilities)." ) )
.arg ( SYSTEM_SAMPLE_RATE_HZ );
}
}
Expand All @@ -404,7 +403,7 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )

if ( AudioObjectGetPropertyData ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, &iPropertySize, &outputSampleRate ) )
{
return QString ( tr ( "The audio output device is no longer available." ) );
return QString ( tr ( "The audio output device is no longer available. Please check if your output device is connected correctly." ) );
}

if ( outputSampleRate != fSystemSampleRate )
Expand All @@ -413,10 +412,9 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
if ( AudioObjectSetPropertyData ( audioOutputDevice[iDriverIdx], &stPropertyAddress, 0, NULL, sizeof ( Float64 ), &fSystemSampleRate ) !=
noErr )
{
return QString ( tr ( "Current system audio output device sample "
"rate of %1 Hz is not supported. Please open the Audio-MIDI-Setup in "
"Applications->Utilities and try to set a sample rate of %2 Hz." ) )
.arg ( static_cast<int> ( outputSampleRate ) )
return QString ( tr ( "The sample rate on the current output device isn't %1 Hz and is therefore incompatible. "
"Please select another device or try setting the sample rate to %1 Hz "
"manually via Audio-MIDI-Setup (in Applications->Utilities)." ) )
.arg ( SYSTEM_SAMPLE_RATE_HZ );
}
}
Expand Down Expand Up @@ -462,8 +460,9 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
( CurDevStreamFormat.mBitsPerChannel != 32 ) || ( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsFloat ) ) ||
( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsPacked ) ) )
{
return tr ( "The audio input stream format for this audio device is "
"not compatible with this software." );
return QString ( tr ( "The stream format on the current input device isn't "
"compatible with this software. Please select another device." ) )
.arg ( APP_NAME );
}

// check the output
Expand All @@ -473,8 +472,9 @@ QString CSound::CheckDeviceCapabilities ( const int iDriverIdx )
( CurDevStreamFormat.mBitsPerChannel != 32 ) || ( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsFloat ) ) ||
( !( CurDevStreamFormat.mFormatFlags & kAudioFormatFlagIsPacked ) ) )
{
return tr ( "The audio output stream format for this audio device is "
"not compatible with this software." );
return QString ( tr ( "The stream format on the current output device isn't "
"compatible with %1. Please select another device." ) )
.arg ( APP_NAME );
}

// store the input and out number of channels for this device
Expand Down Expand Up @@ -726,8 +726,8 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
// Error message string: in case buffer sizes on input and output cannot be
// set to the same value
const QString strErrBufSize = tr ( "The buffer sizes of the current "
"input and output audio device cannot be set to a common value. Please "
"choose other input/output audio devices in your system settings." );
"input and output audio device can't be set to a common value. Please "
"select different input/output devices in your system settings." );

// try to set input buffer size
iActualMonoBufferSize = SetBufferSize ( audioInputDevice[lCurDev], true, iNewPrefMonoBufferSize );
Expand Down
22 changes: 8 additions & 14 deletions src/soundbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ QString CSoundBase::SetDev ( const QString strDevName )
LoadAndInitializeDriver ( strCurDevName, false );

// store error return message
strReturn = QString ( tr ( "The selected audio device could not be used "
strReturn = QString ( tr ( "Can't use the selected audio device "
"because of the following error: " ) ) +
strErrorMessage + QString ( tr ( " The previous driver will be selected." ) );
}
Expand Down Expand Up @@ -154,10 +154,9 @@ QString CSoundBase::SetDev ( const QString strDevName )
if ( !strDevName.isEmpty() )
{
strReturn = tr ( "The previously selected audio device "
"is no longer available or the audio driver properties have changed to a state which "
"is incompatible with this software. We now try to find a valid audio device. This new "
"audio device might cause audio feedback. So, before connecting to a server, please "
"check the audio device setting." );
"is no longer available or the driver has changed to an incompatible state."
"We'll attempt to find a valid audio device, but this new audio device may cause feedback."
"Before connecting to a server, please check your audio device settings." );
}

// try to load and initialize any valid driver
Expand All @@ -166,13 +165,8 @@ QString CSoundBase::SetDev ( const QString strDevName )
if ( !vsErrorList.isEmpty() )
{
// create error message with all details
QString sErrorMessage = "<b>" + tr ( "No usable " ) + strSystemDriverTechniqueName +
tr ( " audio device "
"(driver) found." ) +
"</b><br><br>" +
tr ( "In the following there is a list of all available drivers "
"with the associated error message:" ) +
"<ul>";
QString sErrorMessage = "<b>" + QString ( tr ( "No usable %1 audio device found." ) ).arg ( strSystemDriverTechniqueName ) +
"</b><br><br>" + tr ( "These are all the available drivers with error messages:" ) + "<ul>";

for ( int i = 0; i < lNumDevs; i++ )
{
Expand All @@ -184,14 +178,14 @@ QString CSoundBase::SetDev ( const QString strDevName )
// to be able to access the ASIO driver setup for changing, e.g., the sample rate, we
// offer the user under Windows that we open the driver setups of all registered
// ASIO drivers
sErrorMessage = sErrorMessage + "<br/>" + tr ( "Do you want to open the ASIO driver setups?" );
sErrorMessage += "<br/>" + tr ( "Do you want to open the ASIO driver setup to try changing your configuration to a working state?" );

if ( QMessageBox::Yes == QMessageBox::information ( nullptr, APP_NAME, sErrorMessage, QMessageBox::Yes | QMessageBox::No ) )
{
LoadAndInitializeFirstValidDriver ( true );
}

sErrorMessage = APP_NAME + tr ( " could not be started because of audio interface issues." );
sErrorMessage = QString ( tr ( "Can't start %1. Please restart %1 and check/reconfigure your audio settings." ) ).arg ( APP_NAME );
#endif

throw CGenErr ( sErrorMessage );
Expand Down
Loading

0 comments on commit 40d4b47

Please sign in to comment.