Загрузка данных


/* !!! NEW: Динамическое пересоздание генераторов тонов под актуальный рейсинг моста */
pj_status_t app_recreate_tones(unsigned current_rate)
{
    pj_status_t status;
    unsigned i;
    unsigned samples_per_frame;
    pjmedia_tone_desc tone[RING_CNT+RINGBACK_CNT];
    pj_str_t name;

    // 1. Если порты уже существовали в старом мосту — удаляем их из конференции и памяти
    if (app_config.ringback_slot != PJSUA_INVALID_ID) {
        pjsua_conf_remove_port(app_config.ringback_slot);
        app_config.ringback_slot = PJSUA_INVALID_ID;
    }
    if (app_config.ringback_port) {
        pjmedia_port_destroy(app_config.ringback_port);
        app_config.ringback_port = NULL;
    }
    if (app_config.ring_slot != PJSUA_INVALID_ID) {
        pjsua_conf_remove_port(app_config.ring_slot);
        app_config.ring_slot = PJSUA_INVALID_ID;
    }
    if (app_config.ring_port) {
        pjmedia_port_destroy(app_config.ring_port);
        app_config.ring_port = NULL;
    }

    if (app_config.no_tones == PJ_TRUE) return PJ_SUCCESS;

    // 2. Рассчитываем размер кадра под НОВУЮ частоту моста
    samples_per_frame = app_config.media_cfg.audio_frame_ptime * 
                        current_rate *
                        app_config.media_cfg.channel_count / 1000;

    /* --- Создаем Ringback tone под новую частоту --- */
    name = pj_str("ringback");
    status = pjmedia_tonegen_create2(app_config.pool, &name, 
                                     current_rate, // <-- Используем актуальный рейт
                                     app_config.media_cfg.channel_count, 
                                     samples_per_frame,
                                     16, PJMEDIA_TONEGEN_LOOP, 
                                     &app_config.ringback_port);
    if (status != PJ_SUCCESS) return status;

    pj_bzero(&tone, sizeof(tone));
    for (i=0; i<RINGBACK_CNT; ++i) {
        tone[i].freq1 = RINGBACK_FREQ1;
        tone[i].freq2 = RINGBACK_FREQ2;
        tone[i].on_msec = RINGBACK_ON;
        tone[i].off_msec = RINGBACK_OFF;
    }
    tone[RINGBACK_CNT-1].off_msec = RINGBACK_INTERVAL;
    pjmedia_tonegen_play(app_config.ringback_port, RINGBACK_CNT, tone, PJMEDIA_TONEGEN_LOOP);

    status = pjsua_conf_add_port(app_config.pool, app_config.ringback_port, &app_config.ringback_slot);
    if (status != PJ_SUCCESS) return status;

    /* --- Создаем Ring (Ringer) под новую частоту --- */
    name = pj_str("ring");
    status = pjmedia_tonegen_create2(app_config.pool, &name, 
                                     current_rate, // <-- Используем актуальный рейт
                                     app_config.media_cfg.channel_count, 
                                     samples_per_frame,
                                     16, PJMEDIA_TONEGEN_LOOP, 
                                     &app_config.ring_port);
    if (status != PJ_SUCCESS) return status;

    for (i=0; i<RING_CNT; ++i) {
        tone[i].freq1 = RING_FREQ1;
        tone[i].freq2 = RING_FREQ2;
        tone[i].on_msec = RING_ON;
        tone[i].off_msec = RING_OFF;
    }
    tone[RING_CNT-1].off_msec = RING_INTERVAL;
    pjmedia_tonegen_play(app_config.ring_port, RING_CNT, tone, PJMEDIA_TONEGEN_LOOP);

    status = pjsua_conf_add_port(app_config.pool, app_config.ring_port, &app_config.ring_slot);
    
    return status;
}