Commit 313f638e authored by Mikhail Karpenko's avatar Mikhail Karpenko

Process audio between video frames

parent b50eb743
This diff is collapsed.
......@@ -223,6 +223,7 @@ typedef struct {
int max_frames;
int set_max_frames;
int frames_per_chunk; ///< QuickTime, the number of samples (images or audio samples) in a chunk
unsigned int chunk_frame_cntr; ///< QuickTime, number of video frames recorded in current chunk
int set_frames_per_chunk; ///< QuickTime, index for fast forward (sample-to-chunk atom)
int frameno; ///< total image frame counter, does not include audio samples
unsigned long *frame_lengths; ///< QuickTime; pointer to an array of frame lengths wich includes both image frames
......
This diff is collapsed.
......@@ -25,8 +25,8 @@
#include <sys/time.h>
#include <alsa/asoundlib.h>
#define SAMPLE_RATE 44100
#define SAMPLE_CHANNELS 2
#define SAMPLE_RATE 44100 ///< default sampling rate
#define SAMPLE_CHANNELS 2 ///< default number of audio channels
#define SAMPLE_TIME 200 ///< restrict ALSA to have this period, in milliseconds
#define BUFFER_TIME 1000 ///< approximate ALSA buffer duration, in milliseconds
#define DEFAULT_SND_DEVICE "plughw:0,0"
......@@ -36,27 +36,34 @@
#define AUDIO_RATE_MAX 44100
#define DEFAULT_AUDIO_VOLUME 0xffff
/**
* @brief Audio recording context related to stream management.
* Members of this structure should not be used outside audio module.
*/
struct context_audio {
char *sbuffer; ///< buffer for audio samples
long sbuffer_len; ///< the length of samples buffer in samples
long sbuffer_len; ///< total length of audio buffer, in audio frames
long sbuffer_pos; ///< pointer to current write position in audio buffer, in frames
long read_frames; ///< read granularity, in frames
long sample_time; ///< duration of one chunk of audio data, in ms
struct timeval time_start; ///< start time, set only when stream starts and updated with each new file
struct timeval time_last; ///< calculated time of last audio sample (this value is not taken from ALSA)
long rem_samples; ///< remaining samples
int begin_of_stream_with_audio; ///<
int audio_trigger; ///< indicates the beginning of audio recording to make some initial set ups
long long audio_skip_samples; ///<
snd_pcm_format_t audio_format; ///< format of audio samples as defined in 'enum snd_pcm_format_t'
snd_pcm_t *capture_hnd; ///< ALSA PCM handle
};
/**
* @brief Various parameters related to audio recording.
*/
struct audio {
int audio_enable; ///< flag indicating that audio is enabled
int audio_rate; ///< sample rate, in Hz
int audio_channels; ///< number of channels
int audio_volume; ///< volume set in range [0..0xFFFF]
int sync_port; ///< synch audio stream to this sensor port
int set_audio_enable; ///< temporary storage for new value
int set_audio_rate; ///< temporary storage for new value
......@@ -74,27 +81,24 @@ struct audio {
struct timeval ts_audio; ///< time stamp when audio stream started
struct timeval ts_video; ///< time stamp of each new frame
struct timeval ts_video_start; ///< time stamp of starting video frame
int frame_period; ///< video frame period, in microseconds
snd_pcm_format_t audio_format; ///< format of audio samples as defined in 'enum snd_pcm_format_t'
int frame_period_us; ///< video frame period measured for #sync_port, in microseconds
unsigned long audio_skip_samples; ///< skip this number audio frames to sync to video
int begin_of_stream_with_audio; ///< flag indicating that A/V sync is in progress
int audio_trigger; ///< indicates the beginning of audio recording to make some initial set ups
bool save_data; ///< flag indicating that audio data should be recorded, otherwise audio frames should be
///< stored in buffer for delayed recording
unsigned int sleep_period_us; ///< sleep period between frames while processing audio stream, in microseconds
void (*get_fpga_time)(const struct audio *audio, struct timeval *tv);//< callback function which can get FPGA time
int (*write_samples)(struct audio *audio, void *buff, long len, long slen); ///< callback function which actually write data to file, this must be set
///< in the camogm_init_* function when appropriate format is selected
// === debug ===
struct timeval sf_timediff; // system to fpga time difference at the beginning of the stream
struct timeval m_len;
struct timeval sys_fpga_timediff;
int avail_samples;
long calc_frames; // calculated number of frames by current video frame
struct timeval prev_ts_video;
long long skip_samples;
// === end of debug ===
};
void audio_init(struct audio *audio, bool restart);
void audio_start(struct audio *audio);
void audio_init_hw(struct audio *audio, bool restart);
void audio_init_sw(struct audio *audio, bool restart, int frames);
void audio_process(struct audio *audio);
void audio_finish(struct audio *audio, bool reset);
void audio_set_volume(int nvolume);
unsigned long audio_get_hw_buffer_max(void);
#endif /* _CAMOGM_AUDIO_H */
......@@ -26,11 +26,7 @@
#include <sys/types.h>
#include <assert.h>
// for debug only
#include <math.h>
#include "camogm_mov.h"
#include "thelper.h"
/** @brief QuickTime header length (w/o index tables) enough to accommodate static data */
#define QUICKTIME_MIN_HEADER 0x300
......@@ -228,9 +224,9 @@ int camogm_frame_mov(camogm_state *state)
/**
* Write audio samples to file.
* @param[in] buff pointer to buffer containing audio samples
* @param[in] buff pointer to buffer containing audio frames
* @param[in] len the size of buffer, in bytes
* @param[in] slen the number of audio samples in buffer
* @param[in] slen the number of audio frames in buffer
* @return 0 if data was recorded successfully and negative error code otherwise
*/
static int camogm_audio_mov(struct audio *audio, void *buff, long len, long slen)
......@@ -240,7 +236,7 @@ static int camogm_audio_mov(struct audio *audio, void *buff, long len, long slen
ssize_t wr_len;
camogm_state *state = container_of(audio, camogm_state, audio);
D6(fprintf(debug_file, "write audio sample, len = %ld, slen = %ld\n", len, slen));
D6(fprintf(debug_file, "write audio chunk, len = %ld, slen = %ld\n", len, slen));
wr_len = write(state->ivf, buff, len);
if (wr_len < len) {
......@@ -289,19 +285,15 @@ int camogm_end_mov(camogm_state *state)
q_template, // string containing header template
state->ivf, // output file descriptor (opened)
state->width, // width in pixels
state->height,
state->height, // height in pixels
state->frameno, // the number of image frames
state->frame_period[port] / (1000000 / timescale),
state->frames_per_chunk,
0, // frame size - will look in the table
(int)((float)timescale / (state->timescale)),
// state->frame_lengths, // array of frame lengths to build an index
NULL, // array of frame lengths to build an index
state->frame_data_start
);
// === debug code ===
fprintf(debug_file, "total # of video frames: %d, total # of audio samples: %ld\n", state->frameno, state->audio.audio_samples);
// === end of debug ===
close(state->ivf);
state->ivf = -1;
// free memory used for index
......@@ -640,11 +632,6 @@ int quicktime_template_parser( camogm_state *state,
iFileLen = strlen(iFile);
lseek(ofd, 0, SEEK_SET);
// === debug ===
struct timeval m_len = state->audio.m_len; // duration of movie
fprintf(debug_file, "frameno: %d, duration: %ld:%06ld, audio_samples: %ld\n", state->frameno, m_len.tv_sec, m_len.tv_usec, state->audio.audio_samples);
// === ebd of debug ===
audio_timescale = state->audio.audio_rate;
audio_rate = audio_timescale; // QuickTime defines sample rate as unsigned 16.16 fixed-point number
audio_rate <<= 16;
......
......@@ -51,36 +51,3 @@ int time_comp(struct timeval *t1, struct timeval *t2)
}
return -1;
}
/**
* Subtract one time value from another and return the difference
* @param tv1 time value to subtract from
* @param tv2 time value to be subtracted
* @return tv1 - tv2
*/
struct timeval time_sub(const struct timeval *tv1, const struct timeval *tv2)
{
struct timeval ret_val = *tv1;
ret_val.tv_sec -= 1;
ret_val.tv_usec += 1000000;
ret_val.tv_sec -= tv2->tv_sec;
ret_val.tv_usec -= tv2->tv_usec;
time_normalize(&ret_val);
return ret_val;
}
/**
* Add one time value to another and return the sum
*/
struct timeval time_add(const struct timeval *tv1, const struct timeval *tv2)
{
struct timeval ret_val = *tv1;
ret_val.tv_sec += tv2->tv_sec;
ret_val.tv_usec += tv2->tv_usec;
time_normalize(&ret_val);
return ret_val;
}
......@@ -26,8 +26,6 @@
void time_normalize(struct timeval *tv);
int time_comp(struct timeval *t1, struct timeval *t2);
struct timeval time_sub(const struct timeval *tv1, const struct timeval *tv2);
struct timeval time_add(const struct timeval *tv1, const struct timeval *tv2);
/**
* Convert time represented by timeval structure to time in microseconds
......
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