From 1a24bb9254b9a2f8f2cf8edce927ac17549d40c0 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 10 Feb 2015 22:38:30 +0100 Subject: [PATCH] [DEV] change time properties --- airtaudio/Api.cpp | 40 ++++++++++++--------------------------- airtaudio/Api.h | 11 +++++++---- airtaudio/Interface.h | 4 ++-- airtaudio/api/Alsa.cpp | 4 +++- airtaudio/api/Android.cpp | 4 +++- airtaudio/api/Asio.cpp | 4 +++- airtaudio/api/Core.cpp | 4 +++- airtaudio/api/CoreIos.mm | 4 +++- airtaudio/api/Ds.cpp | 4 +++- airtaudio/api/Dummy.cpp | 2 ++ airtaudio/api/Jack.cpp | 4 +++- airtaudio/api/Oss.cpp | 4 +++- airtaudio/api/Pulse.cpp | 4 +++- airtaudio/base.h | 12 ++++++------ 14 files changed, 56 insertions(+), 49 deletions(-) diff --git a/airtaudio/Api.cpp b/airtaudio/Api.cpp index 044e7e6..fac07f9 100644 --- a/airtaudio/Api.cpp +++ b/airtaudio/Api.cpp @@ -43,7 +43,6 @@ const std::vector& airtaudio::genericSampleRate() { airtaudio::Api::Api() : - m_apiHandle(nullptr), m_deviceBuffer(nullptr) { m_device[0] = 11111; m_device[1] = 11111; @@ -55,6 +54,12 @@ airtaudio::Api::~Api() { } +enum airtaudio::error airtaudio::Api::startStream() { + m_startTime = std::chrono::system_clock::now(); + m_duration = std::chrono::duration(0); + return airtaudio::error_none; +} + enum airtaudio::error airtaudio::Api::openStream(airtaudio::StreamParameters *oParams, airtaudio::StreamParameters *iParams, enum audio::format format, @@ -168,13 +173,7 @@ bool airtaudio::Api::probeDeviceOpen(uint32_t /*device*/, } void airtaudio::Api::tickStreamTime() { - // Subclasses that do not provide their own implementation of - // getStreamTime should call this function once per buffer I/O to - // provide basic stream time support. - m_streamTime += (m_bufferSize * 1.0 / m_sampleRate); -#if defined(HAVE_GETTIMEOFDAY) - gettimeofday(&m_lastTickTimestamp, nullptr); -#endif + m_duration += std::chrono::duration((m_bufferSize * 1000000) / m_sampleRate); } long airtaudio::Api::getStreamLatency() { @@ -193,26 +192,11 @@ long airtaudio::Api::getStreamLatency() { return totalLatency; } -double airtaudio::Api::getStreamTime() { +std::chrono::system_clock::time_point airtaudio::Api::getStreamTime() { if (verifyStream() != airtaudio::error_none) { - return 0.0f; + return std::chrono::system_clock::time_point(); } -#if defined(HAVE_GETTIMEOFDAY) - // Return a very accurate estimate of the stream time by - // adding in the elapsed time since the last tick. - struct timeval then; - struct timeval now; - if (m_state != airtaudio::state_running || m_streamTime == 0.0) { - return m_streamTime; - } - gettimeofday(&now, nullptr); - then = m_lastTickTimestamp; - return m_streamTime - + ((now.tv_sec + 0.000001 * now.tv_usec) - - (then.tv_sec + 0.000001 * then.tv_usec)); -#else - return m_streamTime; -#endif + return m_startTime + m_duration; } uint32_t airtaudio::Api::getStreamSampleRate() { @@ -237,8 +221,8 @@ void airtaudio::Api::clearStreamInfo() { m_bufferSize = 0; m_nBuffers = 0; m_userFormat = audio::format_unknow; - m_streamTime = 0.0; - m_apiHandle = nullptr; + m_startTime = std::chrono::system_clock::time_point(); + m_duration = std::chrono::duration(0); m_deviceBuffer = nullptr; m_callbackInfo.callback = 0; m_callbackInfo.isRunning = false; diff --git a/airtaudio/Api.h b/airtaudio/Api.h index e5fc721..8bc2ee0 100644 --- a/airtaudio/Api.h +++ b/airtaudio/Api.h @@ -9,6 +9,7 @@ #define __AIRTAUDIO_API_H__ #include +#include #include #include #include @@ -46,12 +47,12 @@ namespace airtaudio { airtaudio::AirTAudioCallback _callback, airtaudio::StreamOptions* _options); virtual enum airtaudio::error closeStream(); - virtual enum airtaudio::error startStream() = 0; + virtual enum airtaudio::error startStream(); virtual enum airtaudio::error stopStream() = 0; virtual enum airtaudio::error abortStream() = 0; long getStreamLatency(); uint32_t getStreamSampleRate(); - virtual double getStreamTime(); + virtual std::chrono::time_point getStreamTime(); bool isStreamOpen() const { return m_state != airtaudio::state_closed; } @@ -81,8 +82,10 @@ namespace airtaudio { // TODO : Remove this ... airtaudio::CallbackInfo m_callbackInfo; airtaudio::ConvertInfo m_convertInfo[2]; - // TODO : use : std::chrono::system_clock::time_point ... - double m_streamTime; // Number of elapsed seconds since the stream started. + + //std::chrono::system_clock::time_point + std::chrono::time_point m_startTime; //!< start time of the stream (restart at every stop, pause ...) + std::chrono::duration m_duration; //!< duration from wich the stream is started /** * @brief api-specific method that attempts to open a device diff --git a/airtaudio/Interface.h b/airtaudio/Interface.h index af7fb85..d621c92 100644 --- a/airtaudio/Interface.h +++ b/airtaudio/Interface.h @@ -266,9 +266,9 @@ namespace airtaudio { * @brief If a stream is not open, an RtError (type = INVALID_USE) will be thrown. * @return the number of elapsed seconds since the stream was started. */ - double getStreamTime() { + std::chrono::time_point getStreamTime() { if (m_rtapi == nullptr) { - return 0.0; + return std::chrono::time_point(); } return m_rtapi->getStreamTime(); } diff --git a/airtaudio/api/Alsa.cpp b/airtaudio/api/Alsa.cpp index 0e7b5e4..b7180bc 100644 --- a/airtaudio/api/Alsa.cpp +++ b/airtaudio/api/Alsa.cpp @@ -771,6 +771,8 @@ enum airtaudio::error airtaudio::api::Alsa::closeStream() { } enum airtaudio::error airtaudio::api::Alsa::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); // This method calls snd_pcm_prepare if the device isn't already in that state. if (verifyStream() != airtaudio::error_none) { return airtaudio::error_fail; @@ -934,7 +936,7 @@ void airtaudio::api::Alsa::callbackEventOneCycle() { return; // TODO : notify appl: airtaudio::error_warning; } int32_t doStopStream = 0; - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); enum airtaudio::status status = airtaudio::status_ok; if (m_mode != airtaudio::mode_input && m_private->xrun[0] == true) { status = airtaudio::status_underflow; diff --git a/airtaudio/api/Android.cpp b/airtaudio/api/Android.cpp index 6abcc4a..89a3410 100644 --- a/airtaudio/api/Android.cpp +++ b/airtaudio/api/Android.cpp @@ -85,6 +85,8 @@ enum airtaudio::error airtaudio::api::Android::closeStream() { enum airtaudio::error airtaudio::api::Android::startStream() { ATA_INFO("Start Stream"); + // TODO : Check return ... + airtaudio::Api::startStream(); // Can not close the stream now... return airtaudio::error_none; } @@ -108,7 +110,7 @@ enum airtaudio::error airtaudio::api::Android::abortStream() { void airtaudio::api::Android::callBackEvent(void* _data, int32_t _frameRate) { int32_t doStopStream = 0; - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); enum airtaudio::status status = airtaudio::status_ok; if (m_doConvertBuffer[airtaudio::mode_output] == true) { doStopStream = m_callbackInfo.callback(m_userBuffer[airtaudio::mode_output], diff --git a/airtaudio/api/Asio.cpp b/airtaudio/api/Asio.cpp index 34bc9e7..36f9342 100644 --- a/airtaudio/api/Asio.cpp +++ b/airtaudio/api/Asio.cpp @@ -582,6 +582,8 @@ enum airtaudio::error airtaudio::api::Asio::closeStream() { bool stopThreadCalled = false; enum airtaudio::error airtaudio::api::Asio::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); if (verifyStream() != airtaudio::error_none) { return airtaudio::error_fail; } @@ -692,7 +694,7 @@ bool airtaudio::api::Asio::callbackEvent(long bufferIndex) { // Invoke user callback to get fresh output data UNLESS we are // draining stream. if (m_private->drainCounter == 0) { - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); rtaudio::streamStatus status = 0; if (m_mode != airtaudio::mode_input && asioXRun == true) { status |= RTAUDIO_airtaudio::status_underflow; diff --git a/airtaudio/api/Core.cpp b/airtaudio/api/Core.cpp index bf6fdc5..73dfc4b 100644 --- a/airtaudio/api/Core.cpp +++ b/airtaudio/api/Core.cpp @@ -934,6 +934,8 @@ enum airtaudio::error airtaudio::api::Core::closeStream() { } enum airtaudio::error airtaudio::api::Core::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); if (verifyStream() != airtaudio::error_none) { return airtaudio::error_fail; } @@ -1058,7 +1060,7 @@ bool airtaudio::api::Core::callbackEvent(AudioDeviceID _deviceId, // draining stream or duplex mode AND the input/output devices are // different AND this function is called for the input device. if (m_private->drainCounter == 0 && (m_mode != airtaudio::mode_duplex || _deviceId == outputDevice)) { - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); enum airtaudio::status status = airtaudio::status_ok; if ( m_mode != airtaudio::mode_input && m_private->xrun[0] == true) { diff --git a/airtaudio/api/CoreIos.mm b/airtaudio/api/CoreIos.mm index e63eef1..8410734 100644 --- a/airtaudio/api/CoreIos.mm +++ b/airtaudio/api/CoreIos.mm @@ -91,6 +91,8 @@ enum airtaudio::error airtaudio::api::CoreIos::closeStream(void) { enum airtaudio::error airtaudio::api::CoreIos::startStream(void) { ATA_INFO("Start Stream"); + // TODO : Check return ... + airtaudio::Api::startStream(); OSStatus status = AudioOutputUnitStart(m_private->audioUnit); // Can not close the stream now... return airtaudio::error_none; @@ -127,7 +129,7 @@ void airtaudio::api::CoreIos::callBackEvent(void* _data, return; #endif int32_t doStopStream = 0; - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); enum airtaudio::status status = airtaudio::status_ok; if (m_doConvertBuffer[airtaudio::mode_output] == true) { doStopStream = m_callbackInfo.callback(m_userBuffer[airtaudio::mode_output], diff --git a/airtaudio/api/Ds.cpp b/airtaudio/api/Ds.cpp index 3abed2c..7f6900d 100644 --- a/airtaudio/api/Ds.cpp +++ b/airtaudio/api/Ds.cpp @@ -878,6 +878,8 @@ enum airtaudio::error airtaudio::api::Ds::closeStream() { } enum airtaudio::error airtaudio::api::Ds::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); if (verifyStream() != airtaudio::error_none) { return airtaudio::error_fail; } @@ -1040,7 +1042,7 @@ void airtaudio::api::Ds::callbackEvent() { // Invoke user callback to get fresh output data UNLESS we are // draining stream. if (m_private->drainCounter == 0) { - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); rtaudio::streamStatus status = 0; if ( m_mode != airtaudio::mode_input && m_private->xrun[0] == true) { diff --git a/airtaudio/api/Dummy.cpp b/airtaudio/api/Dummy.cpp index bae2707..4f474dc 100644 --- a/airtaudio/api/Dummy.cpp +++ b/airtaudio/api/Dummy.cpp @@ -35,6 +35,8 @@ enum airtaudio::error airtaudio::api::Dummy::closeStream() { } enum airtaudio::error airtaudio::api::Dummy::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); return airtaudio::error_none; } diff --git a/airtaudio/api/Jack.cpp b/airtaudio/api/Jack.cpp index 682aa34..3dd1ebe 100644 --- a/airtaudio/api/Jack.cpp +++ b/airtaudio/api/Jack.cpp @@ -512,6 +512,8 @@ enum airtaudio::error airtaudio::api::Jack::closeStream() { } enum airtaudio::error airtaudio::api::Jack::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); if (verifyStream() != airtaudio::error_none) { return airtaudio::error_fail; } @@ -649,7 +651,7 @@ bool airtaudio::api::Jack::callbackEvent(uint64_t _nframes) { } // Invoke user callback first, to get fresh output data. if (m_private->drainCounter == 0) { - double streamTime = getStreamTime(); + std::chrono::time_point streamTime = getStreamTime(); enum airtaudio::status status = airtaudio::status_ok; if (m_mode != airtaudio::mode_input && m_private->xrun[0] == true) { status = airtaudio::status_underflow; diff --git a/airtaudio/api/Oss.cpp b/airtaudio/api/Oss.cpp index 7031ab4..e949531 100644 --- a/airtaudio/api/Oss.cpp +++ b/airtaudio/api/Oss.cpp @@ -578,6 +578,8 @@ enum airtaudio::error airtaudio::api::Oss::closeStream() { } enum airtaudio::error airtaudio::api::Oss::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); if (verifyStream() != airtaudio::error_none) { return airtaudio::error_fail; } @@ -709,7 +711,7 @@ void airtaudio::api::Oss::callbackEvent() { } // Invoke user callback to get fresh output data. int32_t doStopStream = 0; - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); rtaudio::streamStatus status = 0; if ( m_mode != airtaudio::mode_input && m_private->xrun[0] == true) { diff --git a/airtaudio/api/Pulse.cpp b/airtaudio/api/Pulse.cpp index 155fc71..e11c66f 100644 --- a/airtaudio/api/Pulse.cpp +++ b/airtaudio/api/Pulse.cpp @@ -150,7 +150,7 @@ void airtaudio::api::Pulse::callbackEventOneCycle() { ATA_ERROR("the stream is closed ... this shouldn't happen!"); return; } - double streamTime = getStreamTime(); + std::chrono::system_clock::time_point streamTime = getStreamTime(); enum airtaudio::status status = airtaudio::status_ok; int32_t doStopStream = m_callbackInfo.callback(&m_userBuffer[airtaudio::modeToIdTable(airtaudio::mode_output)][0], &m_userBuffer[airtaudio::modeToIdTable(airtaudio::mode_input)][0], @@ -211,6 +211,8 @@ unlock: } enum airtaudio::error airtaudio::api::Pulse::startStream() { + // TODO : Check return ... + airtaudio::Api::startStream(); if (m_state == airtaudio::state_closed) { ATA_ERROR("the stream is not open!"); return airtaudio::error_invalidUse; diff --git a/airtaudio/base.h b/airtaudio/base.h index e47cc3a..b23376a 100644 --- a/airtaudio/base.h +++ b/airtaudio/base.h @@ -32,9 +32,9 @@ namespace airtaudio { //! Defined error types. /** - * @brief RtAudio callback function prototype. + * @brief airtaudio callback function prototype. * - * All RtAudio clients must create a function of type RtAudioCallback + * All airtaudio clients must create a function of type AirTAudioCallback * to read and/or write data from/to the audio stream. When the * underlying audio system is ready for new input or output data, this * function will be invoked. @@ -51,11 +51,11 @@ namespace airtaudio { * stream was opened. For output-only streams, this argument * will be nullptr. * - * @param _nFrames The number of sample frames of input or output + * @param _nbChunk The number of chunk of input or output * data in the buffers. The actual buffer size in bytes is * dependent on the data type and number of channels in use. * - * @param _streamTime The number of seconds that have elapsed since the + * @param _time The number of seconds that have elapsed since the * stream was started. * * @param _status If non-zero, this argument indicates a data overflow @@ -70,8 +70,8 @@ namespace airtaudio { */ typedef std::function AirTAudioCallback; }