File: mix_buffer.h

package info (click to toggle)
rtpengine 13.5.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,676 kB
  • sloc: ansic: 86,764; perl: 59,422; python: 3,193; sh: 1,030; makefile: 693; asm: 211
file content (82 lines) | stat: -rw-r--r-- 2,679 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#ifndef _MIX_BUFFER_H_
#define _MIX_BUFFER_H_

#include <stdint.h>
#include <stdbool.h>
#include "helpers.h"
#include "ssrc.h"


enum AVSampleFormat;
struct mix_buffer_impl;


/*
 * 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 int64_t, const int64_t);

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, 0, 0);
}


#endif