⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 会议模拟过程中的混音处理部分,总共包括n+1个声源
💻 C
📖 第 1 页 / 共 2 页
字号:
                new_config->primary = codec_get_by_payload(sp->encodings[0]);
        } else if (codec_audio_formats_compatible(new_config->primary, codec_get_by_payload(sp->encodings[0])) == FALSE) {
                /* Request to change primary and format incompatible so
                 * device needs rejigging */
                change_req = TRUE;
                debug_msg("Change primary requested.\n");
        } else {
                /* Request to change primary to compatible coding. */
                sp->encodings[0] = codec_get_payload(new_config->primary);
        }

        if (new_config->render_3d == -1) {
                /* No request to change 3d rendering */
                new_config->render_3d = sp->render_3d;
        } else if (new_config->render_3d != sp->render_3d) {
                change_req = TRUE;
                debug_msg("Change 3d rendering enabled requested.\n");
        }

        if (change_req) {
                /* Store current config in case it reconfig attempt fails */
                prev_config.device    = sp->audio_device;
                prev_config.primary   = codec_get_by_payload(sp->encodings[0]);
                prev_config.render_3d = sp->render_3d;

                if (sp->audio_device) {
                        audio_device_release(sp, sp->audio_device);
                }

                if (audio_device_attempt_config(sp, new_config)) {
                        /* New config acceptable */
                        curr_config = new_config;
                } else if (audio_device_attempt_config(sp, &prev_config)) {
                        /* else attempt to fallback to previous config */
                        curr_config = &prev_config;
                        debug_msg("Fellback to old dev config\n");
                } else {
                        /* Fallback to guaranteed config - something
                         * went badly wrong */
                        ac_destroy(&new_config);
                        audio_device_get_safe_config(&new_config);
                        assert(new_config);

                        if (audio_device_attempt_config(sp, new_config) == FALSE) {
                                /* should never get here */
                                abort();
                        }
                        curr_config = new_config;
                        debug_msg("Fell back to safe config\n");
                }

                debug_msg("0x%08x 0x%08x\n", prev_config.device, curr_config->device);

                if (prev_config.device == curr_config->device) {
                        debug_msg("Restoring ports\n");
                        audio_set_iport(curr_config->device, iport);
                        audio_set_oport(curr_config->device, oport);
                } else {
                        const audio_port_details_t *papd;
                        /* Ports will be squiffy */
                        papd = audio_get_iport_details(curr_config->device, 0);
                        audio_set_iport(curr_config->device, papd->port);
                        papd = audio_get_oport_details(curr_config->device, 0);
                        audio_set_oport(curr_config->device, papd->port);
                }

                audio_loopback(curr_config->device, sp->loopback_gain);

                sp->audio_device  = curr_config->device;
                sp->encodings[0]  = codec_get_payload(curr_config->primary);

                /* If using redundancy check it is still relevent */
                if (sp->num_encodings > 1 && 
                    !codec_audio_formats_compatible(curr_config->primary, codec_get_by_payload(sp->encodings[1]))) {
                        const cc_details_t *ccd;
                        channel_encoder_destroy(&sp->channel_coder);
                        ccd = channel_get_null_coder();
                        channel_encoder_create(ccd->descriptor, &sp->channel_coder);
                        sp->num_encodings = 1;
                }
                sp->render_3d = curr_config->render_3d;
        } else {
                debug_msg("audio device reconfigure - nothing to do.\n");
                if (tx_is_sending(sp->tb)) {
                        tx_stop(sp->tb);
                        tx_start(sp->tb);
                }
        }

        tx_igain_update(sp->tb);

        ac_destroy(&sp->new_config);
        return change_req;
}

int
audio_device_get_safe_config(audio_config **ppac)
{
        if (ac_create(ppac)) {
                audio_config *pac = *ppac;
                pac->device  = audio_get_null_device();
                pac->primary = codec_get_by_name("PCMU-8K-Mono");
                pac->render_3d = FALSE;
                assert(pac->primary); 
                return TRUE;
        }
        return FALSE;
}

/*****************************************************************************/

static int
audio_device_write(session_t *sp, sample *buf, int dur)
{
        const audio_format *ofmt = audio_get_ofmt(sp->audio_device);
        int len;

        assert(dur >= 0);

        if (sp->out_file) {
                snd_write_audio(&sp->out_file, buf, (uint16_t)(dur * ofmt->channels));
        }

        len =  audio_write(sp->audio_device, buf, dur * ofmt->channels);

        xmemchk();
        
        return len;
}

/* This function needs to be modified to return some indication of how well
 * or not we are doing.                                                    
 */
int
audio_rw_process(session_t *spi, session_t *spo,  struct s_mixer *ms)
{
        uint32_t cushion_size, read_dur;
        struct s_cushion_struct *c;
	int	trailing_silence, new_cushion, cushion_step, diff;
        const audio_format* ofmt;
	sample	*bufp;

	session_validate(spi);
	session_validate(spo);

        c = spi->cushion;

	if ((read_dur = tx_read_audio(spi->tb)) <= 0) {
		return 0;
	} else {
                if (!spi->audio_device) {
                        /* no device means no cushion */
                        return read_dur;
                }
	}

        xmemchk();

	/* read_dur now reflects the amount of real time it took us to get
	 * through the last cycle of processing. 
         */

	if (spo->lecture == TRUE && spo->auto_lecture == 0) {
                cushion_update(c, read_dur, CUSHION_MODE_LECTURE);
	} else {
                cushion_update(c, read_dur, CUSHION_MODE_CONFERENCE);
	}

	/* Following code will try to achieve new cushion size without
	 * messing up the audio...
	 * First case is when we are in trouble and the output has gone dry.
	 * In this case we write out a complete new cushion with the desired
	 * size. We do not care how much of it is going to be real audio and
	 * how much silence so long as the silence is at the head of the new
	 * cushion. If the silence was at the end we would be creating
	 * another silence gap...
	 */
        cushion_size = cushion_get_size(c);
        ofmt         = audio_get_ofmt(spi->audio_device);

	if (cushion_size < read_dur) {
                debug_msg("catch up! read_dur(%d) > cushion_size(%d)\n",
                        read_dur,
                        cushion_size);
		/* Use a step for the cushion to keep things nicely rounded  */
                /* in the mixing. Round it up.                               */
                new_cushion = cushion_use_estimate(c);
                assert(new_cushion >= 0 && new_cushion < 100000);

                /* The mix routine also needs to know for how long the       */
                /* output went dry so that it can adjust the time.           */
                mix_new_cushion(ms, 
                                cushion_size, 
                                new_cushion, 
                                (read_dur - cushion_size), 
                                &bufp);
                audio_device_write(spo, bufp, new_cushion);
                /* We've blocked for this long for whatever reason           */
                cushion_size    = new_cushion;
        } else {
                trailing_silence = mix_get_audio(ms, read_dur * ofmt->channels, &bufp);
                cushion_step = cushion_get_step(c);
                diff  = 0;
                if (trailing_silence > cushion_step) {
                        /* Check whether we need to adjust the cushion */
                        diff = cushion_diff_estimate_size(c);
                        if (abs(diff) < cushion_step) {
                                diff = 0;
                        }
                } 
                
                /* If diff is less than zero then we must decrease the */
                /* cushion so loose some of the trailing silence.      */
                if (diff < 0 && 
                    mix_active(ms) == FALSE && 
                    source_list_source_count(spi->active_sources) == 0) {
                        /* Only decrease cushion if not playing anything out */
                        uint32_t old_cushion;
                        old_cushion = cushion_get_size(c);
                        if (read_dur > (unsigned)cushion_step) {
                                cushion_step_down(c);
                                if (cushion_get_size(c) != old_cushion) {
                                        debug_msg("Decreasing cushion\n");
                                        read_dur -= cushion_step;
                                }
                        }
                }
                assert(read_dur < 0x7fffffff);
                audio_device_write(spo, bufp, read_dur);
                /*
                 * If diff is greater than zero then we must increase the
                 * cushion so increase the amount of trailing silence.
                 */
                if (diff > 0) {
                        assert(cushion_step > 0);
                        audio_device_write(spo, zero_buf, cushion_step);
                        cushion_step_up(c);
                        debug_msg("Increasing cushion.\n");
                }
        }
        return (read_dur);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -