123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #include "precompile.h"
- #include "audioconf.h"
- #include "audiocontext.h"
- #include "audiolog.h"
- static void process_frame(void *self)
- {
- int mixbuf[SUGGEST_FRAME_SIZE];
- int mixcnt;
- int mixdtmf;
- int i;
- int frame_samples;
- int frame_size;
- audioconf_t *conf = CONTAINING_RECORD(self, audioconf_t, base);
- frame_samples = conf->clock / 1000 * FRAME_TIME;
- frame_size = frame_samples * 2;
- mixcnt = 0;
- mixdtmf = 0;
- memset(mixbuf, 0, sizeof(mixbuf));
- audiocontext_lock(conf->base.ctx);
- for (i = 0; i < conf->arr_member->nelts; ++i) {
- audiostream_t *stream = APR_ARRAY_IDX(conf->arr_member, i, audiostream_t*);
- if (audiostream_get_direction(stream) & STREAM_DIR_READ) {
- apr_status_t status;
- audioframe_t *frm = APR_ARRAY_IDX(conf->arr_frame, i, audioframe_t*);
- frm->size = SUGGEST_FRAME_SIZE;
- status = stream->vtbl->read_frame(stream, frm);
- if (status == APR_SUCCESS && frm->size != frame_size) {
- AUDIO_LOG_DEBUG("audio conf read frame failed, fill with silence frame!");
- memset(frm->buffer, 0, frame_size);
- frm->size = frame_size;
- }
- if (status == APR_SUCCESS) {
- int k;
- short *p = (short*)&frm->buffer[0];
- for (k = 0; k < frame_samples; ++k)
- mixbuf[k] += p[k];
- mixcnt ++;
- if (frm->dtmf)
- mixdtmf = frm->dtmf;
- }
- }
- }
-
- for (i = 0; i < conf->arr_member->nelts; ++i) {
- audiostream_t *stream = APR_ARRAY_IDX(conf->arr_member, i, audiostream_t*);
- short tmp_frm_buf[SUGGEST_FRAME_SIZE];
- audioframe_t tmp_frm = {(char*)&tmp_frm_buf[0], frame_samples*2, 0};
- int k;
- if (audiostream_get_direction(stream) & STREAM_DIR_WRITE) {
- apr_status_t status;
- if (audiostream_get_direction(stream) & STREAM_DIR_READ) {
- audioframe_t *frm = APR_ARRAY_IDX(conf->arr_frame, i, audioframe_t*);
- short *q = (short*)&frm->buffer[0];
- for (k = 0; k < frame_samples; ++k) {
- if (mixcnt == 1) {
- tmp_frm_buf[k] = (short)((mixbuf[k] - (int)q[k]));
- } else {
- tmp_frm_buf[k] = (short)((mixbuf[k] - (int)q[k])/(mixcnt-1));
- }
- }
- if (frm->dtmf == 0)
- frm->dtmf = mixdtmf;
- } else {
- for (k = 0; k < frame_samples; ++k) {
- if (mixcnt != 0) {
- tmp_frm_buf[k] = (short)((mixbuf[k])/(mixcnt));
- } else {
- tmp_frm_buf[k] = (short)mixbuf[k];
- }
- }
- }
- status = stream->vtbl->write_frame(stream, &tmp_frm);
- if (status != APR_SUCCESS) {
- AUDIO_LOG_ERROR("audio conf write frame failed");
- }
- }
- }
- audiocontext_unlock(conf->base.ctx);
- }
- static audiodriver_vtbl_t g_driver_vtbl = {
- &process_frame,
- };
- apr_status_t audioconf_create(apr_pool_t *pool, audioengine_t *engine, int clock, audioconf_t **p_conf)
- {
- audioconf_t *conf;
- conf = apr_palloc(pool, sizeof(audioconf_t));
- memset(conf, 0, sizeof(audioconf_t));
- conf->clock = clock;
- conf->arr_member = apr_array_make(pool, 5, sizeof(audiostream_t*));
- conf->arr_frame = apr_array_make(pool, 5, sizeof(audioframe_t*));
- audiodriver_init(engine, &g_driver_vtbl, &conf->base);
- *p_conf = conf;
- return APR_SUCCESS;
- }
- void audioconf_destroy(audioconf_t *conf)
- {
- //...
- }
- apr_status_t audioconf_add_member(apr_pool_t *pool, audioconf_t *conf, audiostream_t *member_stream)
- {
- APR_ARRAY_PUSH(conf->arr_member, audiostream_t*) = member_stream;
- if (conf->arr_frame->nelts < conf->arr_member->nelts) {
- audioframe_t *frm = apr_palloc(pool, sizeof(audioframe_t));
- frm->size = SUGGEST_FRAME_SIZE;
- frm->buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
- frm->dtmf = 0;
- APR_ARRAY_PUSH(conf->arr_frame, audioframe_t*) = frm;
- }
- return APR_SUCCESS;
- }
- apr_status_t audioconf_remove_member(audioconf_t *conf, audiostream_t *member_stream)
- {
- int i ;
- for (i = 0; i < conf->arr_member->nelts; ++i) {
- audiostream_t *t = APR_ARRAY_IDX(conf->arr_member, i, audiostream_t*);
- if (t == member_stream) {
- if (i != conf->arr_member->nelts-1) {
- audiostream_t *tt = APR_ARRAY_IDX(conf->arr_member, i, audiostream_t*);
- APR_ARRAY_IDX(conf->arr_member, i, audiostream_t*) = APR_ARRAY_IDX(conf->arr_member, conf->arr_member->nelts-1, audiostream_t*);
- APR_ARRAY_IDX(conf->arr_member, conf->arr_member->nelts-1, audiostream_t*) = tt;
- }
- apr_array_pop(conf->arr_member);
- return APR_SUCCESS;
- }
- }
- return APR_NOTFOUND;
- }
|