Commit 07e65a43 authored by Mikhail Karpenko's avatar Mikhail Karpenko

Use delta between FPGA time and ALSA time for SR timestamps

ALSA reports monotonic timestamps regardles of the time stamps type set
by snd_pcm_params_set_tstamp_type(). Calculate delta between FPGA time
and ALSA time when audio stream starts and use this delta to correct
time stamps in SR packets.
parent 58b954f2
This diff is collapsed.
......@@ -52,10 +52,10 @@ public:
void Stop(void);
protected:
// int fd;
snd_pcm_t *capture_handle; // PCM handle, returned from snd_pcm_open
short *sbuffer;
snd_pcm_t *capture_handle; //< PCM handle, returned from snd_pcm_open
short *sbuffer; //< buffer for sound data
long sbuffer_len;
bool _present; // flag indicating that audio interface has been initialized
bool _present; //< flag indicating that audio interface has been initialized
long _sample_rate;
long _channels;
long _volume;
......@@ -66,9 +66,13 @@ protected:
void set_capture_volume(int volume);
uint64_t timestamp_rtcp;
long delta_fpga_sys; // A/V clocks delta for RTCP
long delta_fpga_sys; //< A/V clocks delta for RTCP
// bool is_first;
// bool is_first2;
long long delta_fpga_alsa; //< time delta between FPGA time and time reported by ALSA, in microseconds
unsigned char *packet_buffer; //< buffer for RTP packet data (header plus PCM samples)
private:
long long get_delta_fpga_alsa(void); //< return time delta between FPGA time and time stamps reported by ALSA, in microseconds
};
#endif // _AUDIO__H_
/**
* @file FILENAME
* @brief BRIEF DESCRIPTION
* @copyright Copyright (C) YEAR Elphel Inc.
* @file helper.h
* @brief Various time helper functions to work with \e timeval structures
* @copyright Copyright (C) 2017 Elphel Inc.
* @author AUTHOR <EMAIL>
*
* @par License:
......@@ -54,4 +54,19 @@ inline struct timeval time_minus(struct timeval tv_1, const struct timeval &tv_2
return tv_1;
}
#endif
/**
* @brief Add microseconds to a value represented by \e timeval structure
* @param tv time to which microseconds should be added
* @param us the value of microseconds
* @return The sum of two values
*/
inline struct timeval time_plus_us(struct timeval &tv, unsigned long us)
{
tv.tv_usec += us;
tv.tv_sec += tv.tv_usec / 1000000;
tv.tv_usec = tv.tv_usec % 1000000;
return tv;
}
#endif /* __H_HELPER__ */
......@@ -119,3 +119,19 @@ bool Parameters::daemon_enabled(void) {
void Parameters::setPValue(unsigned long *val_array, int count) {
this->write(val_array, sizeof(unsigned long) * count);
}
/**
* @brief Get current FPGA time
* @return Time value in \e timeval structure
*/
struct timeval Parameters::get_fpga_time(void)
{
struct timeval tv;
unsigned long write_data[] = {FRAMEPARS_GETFPGATIME, 0};
write(write_data, sizeof(unsigned long) * 2);
tv.tv_sec = getGPValue(G_SECONDS);
tv.tv_usec = getGPValue(G_MICROSECONDS);
return tv;
}
......@@ -48,6 +48,7 @@ public:
bool daemon_enabled(void);
void setPValue(unsigned long *val_array, int count);
inline int get_port_num() const {return sensor_port;}
struct timeval get_fpga_time(void);
protected:
// static Parameters *_parameters;
......
......@@ -50,21 +50,19 @@ protected:
static void *pthread_f(void *_this);
void *thread(void);
pthread_mutex_t pthm_flow;
// virtual bool process(void) = 0;
virtual long process(void) = 0;
int _ptype;
bool _play;
/// semaphore to wait 'play' event
sem_t sem_play;
sem_t sem_play; //< semaphore to wait 'play' event
Socket *rtp_socket;
Socket *rtcp_socket;
unsigned short packet_num;
unsigned short packet_num; //< sequence number in RTP packet header
unsigned long SSRC;
struct timeval f_tv;
struct timeval rtcp_tv; // time of last SR
struct timeval rtcp_tv; //< time of last SR
long rtcp_delay;
unsigned long timestamp;
......
......@@ -278,7 +278,8 @@ int Streamer::update_settings(bool apply) {
f_audio_channels = true;
if ((audio_proc || session->process_audio) && (f_audio_rate || f_audio_channels))
audio_was_changed = true;
D(sensor_port, cerr << "audio_proc = " << audio_proc << ", process_audio = " << session->process_audio << ", f_audio_rate = " << f_audio_rate << "f_audio_channels = " << f_audio_channels << endl);
D(sensor_port, cerr << "audio_proc = " << audio_proc << ", process_audio = " << session->process_audio << ", f_audio_rate = " << f_audio_rate
<< ", f_audio_channels = " << f_audio_channels << endl);
if (apply) {
bool audio_restarted = false;
if (audio_was_changed) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment