[Summary] Added actions to handle abnormal behavior during stream stop for MIDI and Audio devices.

Made correct error handling for cases we didn't see before.
Removed redundant and experimental code I forgot to remove months ago.
Added debug output which will help in future testing

Conflicts:
	libs/ardour/ardour/audioengine.h
	libs/ardour/engine_state_controller.cc
	libs/backends/wavesaudio/waves_midi_device.cc
This commit is contained in:
Greg Zharun 2015-02-28 18:38:45 +02:00 committed by Paul Davis
parent ce069da682
commit a2f82f8c5d
4 changed files with 99 additions and 105 deletions

View file

@ -605,7 +605,8 @@ WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate)
//make the change...
m_CurrentSamplingRate = newRate;
PaError paErr = PaAsio_SetStreamSampleRate (m_PortAudioStream, m_CurrentSamplingRate);
PaError paErr = PaAsio_SetStreamSampleRate (m_PortAudioStream, m_CurrentSamplingRate);
std::cout << "Sleeping after sample rate change " << std::endl;
Pa_Sleep(PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); // sleep some time to make sure the change has place
if (paErr != paNoError)
@ -655,14 +656,6 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
WTErr retVal = eNoErr;
std::vector<int>::iterator intIter;
//changes the status.
int oldSize = CurrentBufferSize();
bool oldActive = Active();
//same size, nothing to do.
if (oldSize == newSize)
return (retVal);
if (Streaming())
{
//Can't change, perhaps use an "in use" type of error
@ -670,44 +663,17 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
return (retVal);
}
std::cout << "Setting buffer: " << newSize << std::endl;
//see if this is one of our supported rates...
intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), newSize);
if (intIter == m_BufferSizes.end())
// Buffer size for ASIO devices can be changed from the control panel only
// We have driver driven logi here
if (m_CurrentBufferSize != newSize )
{
//Sample rate proposed by client is not supported any more
if (m_BufferSizes.size() == 1)
{
// we have only one aloved buffer size which is preffered by PA
// this is the only value which could be set
newSize = m_BufferSizes[0];
int bufferSize = newSize;
// notify client to update sample rate after us
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
return retVal;
} else {
// more then one buffer size value is available
//Can't change, perhaps use an "invalid param" type of error
retVal = eCommandLineParameter;
return (retVal);
}
}
if (oldActive)
{
//Deactivate it for the change...
SetActive (false);
}
//make the change...
m_CurrentBufferSize = newSize;
//reactivate it.
if (oldActive)
{
retVal = SetActive (true);
// we have only one aloved buffer size which is preffered by PA
// this is the only value which could be set
newSize = m_BufferSizes[0];
int bufferSize = newSize;
// notify client to update buffer size
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
return retVal;
}
return (retVal);
@ -751,17 +717,6 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
// if device is not active activate it
if (!Active() )
{
std::list<long> buffersSizes;
buffersSizes.push_back(m_CurrentBufferSize);
long minSize, maxSize, preferredSize, granularity;
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
if (paErr == paNoError)
{
buffersSizes.push_front(preferredSize);
}
PaStreamParameters inputParameters, outputParameters;
PaStreamParameters *pInS = NULL, *pOutS = NULL;
@ -786,27 +741,20 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
if (outputParameters.channelCount)
pOutS = &outputParameters;
// try opening stream with current buffer and the rest if not successful
std::list<long>::const_iterator bufferIter = buffersSizes.begin();
for (; bufferIter != buffersSizes.end(); ++bufferIter) {
std::cout << "API::Device" << m_DeviceName << " Opening device stream " << std::endl;
std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << *bufferIter << std::endl;
paErr = Pa_OpenStream(&m_PortAudioStream,
pInS,
pOutS,
m_CurrentSamplingRate,
m_CurrentBufferSize,
paDitherOff,
WCMRPortAudioDevice::TheCallback,
this);
std::cout << "API::Device " << m_DeviceName << " Opening device stream " << std::endl;
std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << m_CurrentBufferSize << std::endl;
paErr = Pa_OpenStream(&m_PortAudioStream,
pInS,
pOutS,
m_CurrentSamplingRate,
m_CurrentBufferSize,
paDitherOff,
WCMRPortAudioDevice::TheCallback,
this);
if(paErr == paNoError)
{
break;
}
std::cout << "Cannot open streamm with buffer: "<< *bufferIter << " Error: " << Pa_GetErrorText (paErr) << std::endl;
if(paErr != paNoError)
{
std::cout << "Cannot open streamm with buffer: "<< m_CurrentBufferSize << " Error: " << Pa_GetErrorText (paErr) << std::endl;
if (paErr == paUnanticipatedHostError)
std::cout << "Error details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl;
@ -814,11 +762,16 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
if(paErr == paNoError)
{
std::cout << "Stream has been opened! "<< std::endl;
// check for possible changes
long minSize, maxSize, preferredSize, granularity;
PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
std::cout << "Checked if buffer size changed "<< std::endl;
if (paErr == paNoError && m_CurrentBufferSize != preferredSize)
{
std::cout << "Buffer size has changed "<< std::endl;
m_CurrentBufferSize = preferredSize;
m_BufferSizes.clear();
m_BufferSizes.push_back(preferredSize);
@ -837,6 +790,7 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
m_ResetReported = 0;
m_ResyncRequested = 0;
m_ResyncReported = 0;
std::cout << "Installing new mesage hook "<< std::endl;
PaAsio_SetMessageHook (StaticASIOMessageHook, this);
}
m_IsActive = true;
@ -855,6 +809,8 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
}
std::cout << "Activation is DONE "<< std::endl;
if (callerIsWaiting)
SetEvent(m_hActivationDone);
}
@ -987,7 +943,7 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
std::cout << "API::Device " << m_DeviceName << " Stopping device stream" << std::endl;
paErr = Pa_StopStream( m_PortAudioStream );
if(paErr == paNoError)
if(paErr == paNoError || paErr == paStreamIsStopped)
{
// if the stream was stopped successfully
m_IsStreaming = false;
@ -995,9 +951,23 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
}
else
{
std::cout << "Failed to stop PA stream: " << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to stop PA stream " << Pa_GetErrorText (paErr) );
m_lastErr = eGenericErr;
std::cout << "Failed to stop PA stream normaly! Aborting the stream. Error:" << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to stop PA stream normaly! Aborting the stream. Error:" << Pa_GetErrorText (paErr) );
Pa_Sleep(PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); // sleep some time to make sure the change has place
PaError abortionError = Pa_AbortStream( m_PortAudioStream );
if(abortionError == paNoError || abortionError == paStreamIsStopped)
{
// if the stream was stopped successfully
m_IsStreaming = false;
m_pInputData = NULL;
}
else
{
std::cout << "Failed to stop PA stream: " << Pa_GetErrorText (paErr) << std::endl;
DEBUG_MSG( "Failed to stop PA stream " << Pa_GetErrorText (paErr) );
m_lastErr = eGenericErr;
}
}
}
@ -1019,8 +989,6 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
//**********************************************************************************************
void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
{
std::cout << "API::Device" << m_DeviceName << "Reseting device" << std::endl;
PaError paErr = paNoError;
// Keep device sates