| 1798 | } |
| 1799 | |
| 1800 | bool RtApiCore ::callbackEvent(AudioDeviceID deviceId, |
| 1801 | const AudioBufferList * inBufferList, |
| 1802 | const AudioBufferList * outBufferList) |
| 1803 | { |
| 1804 | if (stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING) return SUCCESS; |
| 1805 | if (stream_.state == STREAM_CLOSED) |
| 1806 | { |
| 1807 | errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; |
| 1808 | error(RtAudioError::WARNING); |
| 1809 | return FAILURE; |
| 1810 | } |
| 1811 | |
| 1812 | CallbackInfo * info = (CallbackInfo *) &stream_.callbackInfo; |
| 1813 | CoreHandle * handle = (CoreHandle *) stream_.apiHandle; |
| 1814 | |
| 1815 | // Check if we were draining the stream and signal is finished. |
| 1816 | if (handle->drainCounter > 3) |
| 1817 | { |
| 1818 | ThreadHandle threadId; |
| 1819 | |
| 1820 | stream_.state = STREAM_STOPPING; |
| 1821 | if (handle->internalDrain == true) |
| 1822 | pthread_create(&threadId, NULL, coreStopStream, info); |
| 1823 | else // external call to stopStream() |
| 1824 | pthread_cond_signal(&handle->condition); |
| 1825 | return SUCCESS; |
| 1826 | } |
| 1827 | |
| 1828 | AudioDeviceID outputDevice = handle->id[0]; |
| 1829 | |
| 1830 | // Invoke user callback to get fresh output data UNLESS we are |
| 1831 | // draining stream or duplex mode AND the input/output devices are |
| 1832 | // different AND this function is called for the input device. |
| 1833 | if (handle->drainCounter == 0 && (stream_.mode != DUPLEX || deviceId == outputDevice)) |
| 1834 | { |
| 1835 | RtAudioCallback callback = (RtAudioCallback) info->callback; |
| 1836 | double streamTime = getStreamTime(); |
| 1837 | RtAudioStreamStatus status = 0; |
| 1838 | if (stream_.mode != INPUT && handle->xrun[0] == true) |
| 1839 | { |
| 1840 | status |= RTAUDIO_OUTPUT_UNDERFLOW; |
| 1841 | handle->xrun[0] = false; |
| 1842 | } |
| 1843 | if (stream_.mode != OUTPUT && handle->xrun[1] == true) |
| 1844 | { |
| 1845 | status |= RTAUDIO_INPUT_OVERFLOW; |
| 1846 | handle->xrun[1] = false; |
| 1847 | } |
| 1848 | |
| 1849 | int cbReturnValue = callback(stream_.userBuffer[0], stream_.userBuffer[1], |
| 1850 | stream_.bufferSize, streamTime, status, info->userData); |
| 1851 | if (cbReturnValue == 2) |
| 1852 | { |
| 1853 | stream_.state = STREAM_STOPPING; |
| 1854 | handle->drainCounter = 2; |
| 1855 | abortStream(); |
| 1856 | return SUCCESS; |
| 1857 | } |
no test coverage detected