Загрузка данных
#ifdef MY_CODE
/**
* In-place runtime reconfiguration of pjsua_var.mconf fields.
* Updates all internal structures (master_port, ports[0], and delay_buf)
* to 8kHz/160SPF on the fly without freeing the main context memory.
*/
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;
}
old_clock_rate = conf->clock_rate;
// Check if the conference grid parameters actually need alignment
if (old_clock_rate != stream_conf_port->clock_rate) {
printf("[INPLACE_SWAP] Mutating fields: %u Hz -> %u Hz (SPF: %u)\n",
old_clock_rate, stream_conf_port->clock_rate, stream_conf_port->samples_per_frame);
// Step 1: Hardware safety lock
zephyr_i2s_stop(1); // Stop RX
zephyr_i2s_stop(0); // Stop TX
k_msleep(5);
// Step 2: Apply physical clock modification to MCUX SAI & WM8960 Codec registers
int hw_ret = zephyr_i2s_set_rate(stream_conf_port->clock_rate);
if (hw_ret < 0) {
printf("[INPLACE_SWAP] ERROR: Low-level hardware shift failed: %d\n", hw_ret);
return PJ_EINVALIDOP;
}
// Step 3: Mutate main bridge parameters in place
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;
// Step 4: Mutate Master Port internal audio detail parameters
if (conf->master_port) {
pjmedia_audio_format_detail *master_afd;
master_afd = pjmedia_format_get_audio_format_detail(&conf->master_port->info.fmt, 1);
if (master_afd) {
master_afd->clock_rate = conf->clock_rate;
master_afd->samples_per_frame = conf->samples_per_frame;
master_afd->channel_count = conf->channel_count;
}
// Update top-level info values as well
conf->master_port->info.fmt.det.aud.clock_rate = conf->clock_rate;
conf->master_port->info.fmt.det.aud.frame_time_usec = 20000; // 20ms
}
// Step 5: Mutate Sound Card Passive Port (Port 0) values
if (conf->ports && conf->ports[0]) {
struct conf_port *snd_port = conf->ports[0];
snd_port->clock_rate = conf->clock_rate;
snd_port->samples_per_frame = conf->samples_per_frame;
snd_port->channel_count = conf->channel_count;
// Re-allocate adjustment level buffer to reflect new sample processing boundaries
// (Old 16kHz buffer size was 320 words, new is 160. Memory is safe to reuse)
// Step 6: Destructive swap of the inner delay_buf instance only.
// Jitter buffers MUST be fresh because their math calculations rely on fixed sample counts.
if (snd_port->delay_buf) {
pjmedia_delay_buf_destroy(snd_port->delay_buf);
snd_port->delay_buf = NULL;
}
ptime = conf->samples_per_frame * 1000 / conf->clock_rate / conf->channel_count;
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,
0,
&snd_port->delay_buf);
if (status != PJ_SUCCESS) {
printf("[INPLACE_SWAP] ERROR: Jitter buffer rebuild failed: %d\n", status);
return status;
}
}
printf("[INPLACE_SWAP] Field modification complete. All layers synced to %u Hz!\n", conf->clock_rate);
}
return PJ_SUCCESS;
}
#endif