123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #include "precompile.h"
- #include "audiomixer.h"
- #include "audioengine.h"
- static apr_status_t read_frame(void *self, audioframe_t *frame)
- {
- audiomixer_t *mixer = CONTAINING_RECORD(self, audiomixer_t, base);
- apr_status_t status;
- if (mixer->base.downstream == NULL)
- return APR_EGENERAL;
- status = mixer->base.downstream->vtbl->read_frame(mixer->base.downstream, frame);
- if (status == APR_SUCCESS && frame->size) {
- int mixbuf[SUGGEST_FRAME_SIZE];
- int mixcnt;
- int mixdtmf;
- int frame_samples;
- int frame_size;
- int i;
- int kk;
- if (mixer->arr_stream->nelts == 0)
- return status;
- frame_samples = frame->size >> 1;
- frame_size = frame->size;
- mixcnt = 0;
- mixdtmf = 0;
- memset(mixbuf, 0, sizeof(mixbuf));
- for (i = 0; i < mixer->arr_stream->nelts; ++i) {
- audiostream_t *stream = APR_ARRAY_IDX(mixer->arr_stream, i, audiostream_t*);
- if (audiostream_get_direction(stream) & STREAM_DIR_READ) {
- short frm_buf[SUGGEST_FRAME_SIZE];
- audioframe_t frm = {(char*)&frm_buf[0], SUGGEST_FRAME_SIZE};
- status = stream->vtbl->read_frame(stream, &frm);
- if (status == APR_SUCCESS && frm.size == frame->size) {
- for (kk = 0; kk < frame_samples; ++kk)
- mixbuf[kk] += frm_buf[kk];
- if (mixdtmf == 0 && frm.dtmf)
- mixdtmf = frm.dtmf;
- mixcnt ++;
- }
- }
- }
- if (mixcnt > 0) {
- short *dst = (short*)frame->buffer;
- for (kk = 0; kk < frame_samples; ++kk) {
- int t = mixbuf[kk] + dst[kk];
- if (t > 32767)
- t = 32767;
- if (t < -32767)
- t = -32767;
- dst[kk] = (short)t;
- }
- if (frame->dtmf == 0)
- frame->dtmf = mixdtmf;
- }
- } else {
- return status;
- }
- return APR_SUCCESS;
- }
- static apr_status_t write_frame(void *self, const audioframe_t *frame)
- {
- audiomixer_t *mixer = CONTAINING_RECORD(self, audiomixer_t, base);
- if (mixer->base.downstream) {
- return mixer->base.downstream->vtbl->write_frame(mixer->base.downstream, frame);
- } else {
- return APR_EGENERAL;
- }
- }
- static audiostream_vtbl_t g_stream_vtbl = {
- &read_frame,
- &write_frame,
- };
- apr_status_t audiomixer_create(apr_pool_t *pool, audioengine_t *engine, audiomixer_t **p_mixer)
- {
- audiomixer_t *mixer;
- mixer = apr_palloc(pool, sizeof(audiomixer_t));
- memset(mixer, 0, sizeof(audiomixer_t));
- mixer->arr_stream = apr_array_make(pool, 3, sizeof(audiostream_t*));
- audiostream_init(engine, &g_stream_vtbl, &mixer->base);
- *p_mixer = mixer;
- return APR_SUCCESS;
- }
- void audiomixer_destroy(audiomixer_t *mixer)
- {
-
- }
- apr_status_t audiomixer_add_stream(audiomixer_t *mixer, audiostream_t *stream)
- {
- if (!mixer || !stream)
- return APR_EINVAL;
- APR_ARRAY_PUSH(mixer->arr_stream, audiostream_t*) = stream;
- return APR_SUCCESS;
- }
- apr_status_t audiomixer_remove_stream(audiomixer_t *mixer, audiostream_t *stream)
- {
- int i;
- if (!mixer || !stream)
- return APR_EINVAL;
- for (i = 0; i < mixer->arr_stream->nelts; ++i) {
- audiostream_t *t = APR_ARRAY_IDX(mixer->arr_stream, i, audiostream_t*);
- if (t == stream) {
- if (i != mixer->arr_stream->nelts-1)
- APR_ARRAY_IDX(mixer->arr_stream, i, audiostream_t*) = APR_ARRAY_IDX(mixer->arr_stream, mixer->arr_stream->nelts-1, audiostream_t*);
- apr_array_pop(mixer->arr_stream);
- return APR_SUCCESS;
- }
- }
- return APR_NOTFOUND;
- }
|