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


#ifdef MY_CODE
/**
 * Dynamically adapts the conference bridge and the sound device port (Port 0)
 * to the negotiated codec sample rate without destroying the bridge context.
 * Bypasses software resampling by aligning all internal clocks 1:1.
 */
static pj_status_t pjmedia_conf_adapt_to_stream_rate(pjmedia_conf *conf, 
                                                     struct conf_port *stream_conf_port)
{
    unsigned old_clock_rate;
    unsigned ptime;
    pj_str_t passive_name = { "Master/sound", 12 };
    pj_status_t status;

    if (!conf || !stream_conf_port) {
        return PJ_EINVAL;
    }

    // Save previous clock rate to check if modification is actually required
    old_clock_rate = conf->clock_rate;

    // Force update the global conference bridge configuration parameters
    conf->clock_rate = stream_conf_port->clock_rate;
    conf->channel_count = stream_conf_port->channel_count;
    conf->samples_per_frame = stream_conf_port->samples_per_frame;

    // If the clock rate has changed, seamlessly reconfigure Port 0 (Hardware Sound Device)
    if (old_clock_rate != conf->clock_rate && conf->ports != NULL && conf->ports[0] != NULL) {
        struct conf_port *snd_port = conf->ports[0];

        printf("[DYNAMIC_SWAP] Adapting sound Port 0: %u Hz, SPF: %u\n", 
               conf->clock_rate, conf->samples_per_frame);

        // Align hardware port structural limits with the new global rate configuration
        snd_port->clock_rate = conf->clock_rate;
        snd_port->samples_per_frame = conf->samples_per_frame;
        snd_port->channel_count = conf->channel_count;

        // Safely recreate the jitter delay buffer for the sound port to match 8kHz timings
        if (snd_port->delay_buf) {
            pjmedia_delay_buf_destroy(snd_port->delay_buf);
            snd_port->delay_buf = NULL;
        }

        // Calculate dynamic ptime based on new frame metrics (samples * 1000 / rate / channels)
        ptime = conf->samples_per_frame * 1000 / conf->clock_rate / conf->channel_count;
        
        // Re-allocate jitter buffer on the existing sound port memory pool
        status = pjmedia_delay_buf_create(snd_port->pool, passive_name.ptr, 
                                          conf->clock_rate,
                                          conf->samples_per_frame,
                                          conf->channel_count,
                                          RX_BUF_COUNT * ptime, /* Max delay window */
                                          0, /* Options */
                                          &snd_port->delay_buf);
        if (status != PJ_SUCCESS) {
            printf("[DYNAMIC_SWAP] ERROR: Failed to recreate delay_buf: %d\n", status);
            return status;
        }

        // Apply physical clock changes to i.MX RT1024 MCUX SAI peripheral and wm8960 audio codec
        // This stops active DMA, updates I2C registers/dividers, and re-triggers transfers
        int hw_ret = zephyr_i2s_set_rate(conf->clock_rate);
        if (hw_ret < 0) {
            printf("[DYNAMIC_SWAP] ERROR: Low-level driver clock swap failed: %d\n", hw_ret);
            return PJ_EINVALIDOP;
        }
    }

    return PJ_SUCCESS;
}
#endif