mirror of https://github.com/sipwise/rtpengine.git
83 lines
2.6 KiB
83 lines
2.6 KiB
#ifndef _MIX_BUFFER_H_
|
|
#define _MIX_BUFFER_H_
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "helpers.h"
|
|
|
|
|
|
enum AVSampleFormat;
|
|
struct mix_buffer_impl;
|
|
struct ssrc_hash;
|
|
|
|
|
|
/*
|
|
* A simple circular audio buffer that allows mixing multiple sources of
|
|
* audio. Sources are tracked by SSRC and all sources are expected to
|
|
* provide audio in the same format (same clock rate, channels, sample
|
|
* format).
|
|
|
|
* Only one consumer per buffer is supported, which is expected to retrieve
|
|
* buffered audio at regular intervals (ptime) and so continuously empty
|
|
* the buffer.
|
|
|
|
* The first audio source to write into the buffer at the leading edge of
|
|
* the circular buffer has its audio simply copied into the buffer, with
|
|
* the leading edge advanced, while other later sources writing into the
|
|
* buffer mixed into the existing buffered audio at their respective write
|
|
* positions.
|
|
*/
|
|
struct mix_buffer {
|
|
mutex_t lock;
|
|
|
|
union {
|
|
// generic pointers
|
|
void *v;
|
|
char *c;
|
|
|
|
// implementation-specific pointers
|
|
int16_t *s16;
|
|
} buf;
|
|
|
|
unsigned int channels;
|
|
unsigned int clockrate;
|
|
|
|
// all sizes and positions in samples
|
|
unsigned int size; // total size
|
|
unsigned int read_pos; // current read (output) position
|
|
unsigned int head_write_pos; // furthest ahead write (input) position
|
|
unsigned int fill; // difference between read and write position
|
|
unsigned int delay; // initial write delay for new inputs/sources
|
|
|
|
unsigned int loops; // how many times the write pos has circled around
|
|
bool active; // to optionally suppress early media
|
|
|
|
// implementation details
|
|
const struct mix_buffer_impl *impl;
|
|
unsigned int sample_size_channels; // = sample_size * channels
|
|
struct ssrc_hash *ssrc_hash;
|
|
};
|
|
|
|
|
|
bool mix_buffer_init_active(struct mix_buffer *, enum AVSampleFormat, unsigned int clockrate,
|
|
unsigned int channels, unsigned int size_ms, unsigned int delay_ms, bool active);
|
|
#define mix_buffer_init(mb, fmt, clockrate, channels, size_ms, delay_ms) \
|
|
mix_buffer_init_active(mb, fmt, clockrate, channels, size_ms, delay_ms, true)
|
|
INLINE void mix_buffer_activate(struct mix_buffer *mb) {
|
|
LOCK(&mb->lock);
|
|
mb->active = true;
|
|
}
|
|
void mix_buffer_destroy(struct mix_buffer *);
|
|
|
|
void *mix_buffer_read_fast(struct mix_buffer *, unsigned int samples, unsigned int *size);
|
|
void mix_buffer_read_slow(struct mix_buffer *, void *outbuf, unsigned int samples);
|
|
bool mix_buffer_write_delay(struct mix_buffer *, uint32_t ssrc, const void *buf, unsigned int samples,
|
|
const struct timeval *, const struct timeval *);
|
|
|
|
INLINE bool mix_buffer_write(struct mix_buffer *mb, uint32_t ssrc, const void *buf, unsigned int samples) {
|
|
return mix_buffer_write_delay(mb, ssrc, buf, samples, NULL, NULL);
|
|
}
|
|
|
|
|
|
#endif
|