| 1714 | } |
| 1715 | |
| 1716 | bool RtApiCore ::callbackEvent(AudioDeviceID deviceId, |
| 1717 | const AudioBufferList *inBufferList, |
| 1718 | const AudioBufferList *outBufferList) |
| 1719 | { |
| 1720 | if (stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING) return SUCCESS; |
| 1721 | if (stream_.state == STREAM_CLOSED) |
| 1722 | { |
| 1723 | errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; |
| 1724 | error(RtAudioError::WARNING); |
| 1725 | return FAILURE; |
| 1726 | } |
| 1727 | |
| 1728 | CallbackInfo *info = (CallbackInfo *)&stream_.callbackInfo; |
| 1729 | CoreHandle *handle = (CoreHandle *)stream_.apiHandle; |
| 1730 | |
| 1731 | // Check if we were draining the stream and signal is finished. |
| 1732 | if (handle->drainCounter > 3) |
| 1733 | { |
| 1734 | ThreadHandle threadId; |
| 1735 | |
| 1736 | stream_.state = STREAM_STOPPING; |
| 1737 | if (handle->internalDrain == true) |
| 1738 | pthread_create(&threadId, NULL, coreStopStream, info); |
| 1739 | else // external call to stopStream() |
| 1740 | pthread_cond_signal(&handle->condition); |
| 1741 | return SUCCESS; |
| 1742 | } |
| 1743 | |
| 1744 | AudioDeviceID outputDevice = handle->id[0]; |
| 1745 | |
| 1746 | // Invoke user callback to get fresh output data UNLESS we are |
| 1747 | // draining stream or duplex mode AND the input/output devices are |
| 1748 | // different AND this function is called for the input device. |
| 1749 | if (handle->drainCounter == 0 && (stream_.mode != DUPLEX || deviceId == outputDevice)) |
| 1750 | { |
| 1751 | RtAudioCallback callback = (RtAudioCallback)info->callback; |
| 1752 | double streamTime = getStreamTime(); |
| 1753 | RtAudioStreamStatus status = 0; |
| 1754 | if (stream_.mode != INPUT && handle->xrun[0] == true) |
| 1755 | { |
| 1756 | status |= RTAUDIO_OUTPUT_UNDERFLOW; |
| 1757 | handle->xrun[0] = false; |
| 1758 | } |
| 1759 | if (stream_.mode != OUTPUT && handle->xrun[1] == true) |
| 1760 | { |
| 1761 | status |= RTAUDIO_INPUT_OVERFLOW; |
| 1762 | handle->xrun[1] = false; |
| 1763 | } |
| 1764 | |
| 1765 | int cbReturnValue = callback(stream_.userBuffer[0], stream_.userBuffer[1], |
| 1766 | stream_.bufferSize, streamTime, status, info->userData); |
| 1767 | if (cbReturnValue == 2) |
| 1768 | { |
| 1769 | stream_.state = STREAM_STOPPING; |
| 1770 | handle->drainCounter = 2; |
| 1771 | abortStream(); |
| 1772 | return SUCCESS; |
| 1773 | } |
no test coverage detected