[DEV] change time properties

This commit is contained in:
Edouard DUPIN 2015-02-10 22:38:30 +01:00
parent 5c9361c199
commit 1a24bb9254
14 changed files with 56 additions and 49 deletions

View File

@ -43,7 +43,6 @@ const std::vector<uint32_t>& 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<int64_t, std::micro>(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<int64_t, std::micro>((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<int64_t, std::micro>(0);
m_deviceBuffer = nullptr;
m_callbackInfo.callback = 0;
m_callbackInfo.isRunning = false;

View File

@ -9,6 +9,7 @@
#define __AIRTAUDIO_API_H__
#include <sstream>
#include <chrono>
#include <airtaudio/debug.h>
#include <airtaudio/type.h>
#include <airtaudio/state.h>
@ -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<std::chrono::system_clock> 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<std::chrono::system_clock> m_startTime; //!< start time of the stream (restart at every stop, pause ...)
std::chrono::duration<int64_t, std::micro> m_duration; //!< duration from wich the stream is started
/**
* @brief api-specific method that attempts to open a device

View File

@ -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<std::chrono::system_clock> getStreamTime() {
if (m_rtapi == nullptr) {
return 0.0;
return std::chrono::time_point<std::chrono::system_clock>();
}
return m_rtapi->getStreamTime();
}

View File

@ -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;

View File

@ -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],

View File

@ -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;

View File

@ -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) {

View File

@ -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],

View File

@ -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) {

View File

@ -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;
}

View File

@ -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<std::chrono::system_clock> streamTime = getStreamTime();
enum airtaudio::status status = airtaudio::status_ok;
if (m_mode != airtaudio::mode_input && m_private->xrun[0] == true) {
status = airtaudio::status_underflow;

View File

@ -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) {

View File

@ -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;

View File

@ -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<int32_t (void* _outputBuffer,
void* _inputBuffer,
uint32_t _nFrames,
double _streamTime,
uint32_t _nbChunk,
const std::chrono::system_clock::time_point& _time,
airtaudio::status _status)> AirTAudioCallback;
}