#include <pjsua-lib/pjsua.h>
static pj_status_t force_reopen_sound_device(unsigned clock_rate, unsigned channel_count, unsigned samples_per_frame)
{
pjsua_snd_dev_param param;
pj_status_t status;
printf("[AUDIO_REOPEN] Forcing hard reset to %u Hz via pjsua_set_snd_dev2...\n", clock_rate);
/* 1. Инициализируем структуру */
pjsua_snd_dev_param_default(¶m);
pjsua_get_snd_dev2(¶m);
/* 2. Задаем ID устройств */
param.capture_dev = pjsua_var.cap_dev;
param.playback_dev = pjsua_var.play_dev;
param.use_default_settings = PJ_FALSE;
/*
* 3. ТРЮК: Обманываем проверку «No changes in capture and playback devices».
* Мы принудительно инвертируем или меняем режим (например, выставляем неиспользуемый бит),
* чтобы PJSIP подумал, что конфигурация изменилась, и пошел переоткрывать устройство.
*/
unsigned original_mode = pjsua_var.snd_mode;
param.mode = original_mode ^ 0x100; // Мутируем режим для обхода "if"
/* Но убираем флаг задержки открытия, устройство должно открыться немедленно */
param.mode &= ~PJSUA_SND_DEV_NO_IMMEDIATE_OPEN;
/*
* 4. ОБНОВЛЯЕМ ЧАСТОТЫ В СИСТЕМЕ:
* Как видно из вашего кода, функция берет рейт из pjsua_var.media_cfg.snd_clock_rate:
* alt_cr[0] = pjsua_var.media_cfg.snd_clock_rate;
* И вычисляет samples_per_frame на его основе!
*/
pjsua_var.media_cfg.snd_clock_rate = clock_rate;
pjsua_var.media_cfg.clock_rate = clock_rate;
pjsua_var.media_cfg.channel_count = channel_count;
// Пересчитываем ptime (обычно это 20мс)
if (clock_rate > 0) {
pjsua_var.media_cfg.audio_frame_ptime = (samples_per_frame * 1000) / (clock_rate * channel_count);
}
/* 5. Вызываем переоткрытие */
status = pjsua_set_snd_dev2(¶m);
/* 6. Возвращаем оригинальный режим на место, если он нам важен */
pjsua_var.snd_mode = original_mode;
if (status != PJ_SUCCESS) {
printf("[AUDIO_REOPEN] Error: pjsua_set_snd_dev2 failed: %d\n", status);
} else {
printf("[AUDIO_REOPEN] Success! Audio driver and bridge reconfigured to %u Hz\n", clock_rate);
}
return status;
}