#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