До ответа оператора - call-центр выдает в линию стандартные ring tones:
20-100 миллисекунд - фоновый шум при соединении
от 2-х до 6-х секунд - тишина
Дальше по циклу:
1 секунда - тон, 425 Hz
4 секунды - тишина
Оператор может ответить в любой момент, даже без гудков.
Первый вариант (чтобы не лезть в исходники Asteriska):
1. Номер call-центра набираем с опцией "M":
2. После ответа call-центра, но
до соединения каналов - вызовется макрос callcenter.
3. В макросе используем приложения wait, waitForSilence, waitForNoise с таймаутом.
Засекаем время выполнения каждой waitForSilence, waitForNoise, если оно соответствует нашему шаблону (гудки), то остаемся в цикле.
Если не соответствует - завершаем макрос и соединяем каналы.
Код макроса (диалплан на LUA):
Код: Выделить всё
local ringing = 1
local intervalLen = 30 -- интервал (мс), в течение которых должен быть шум/тишина
app.wait(1) -- отсекаем шум в начале соединения
local t1 = tonumber(channel["STRFTIME(${EPOCH},0,%S%3q)"]:get()) -- 30123 (30 - количество секунд в текущей минуте; 123 - миллисекунды)
local t2 = 0
app.waitfornoise(intervalLen,1,6) -- ждем первого гудка, или ответа оператора
t2 = tonumber(channel["STRFTIME(${EPOCH},0,%S%3q)"]:get())
if (t2 < t1) then t2 = t2 + 60000 end -- на случай, если началась новая минута (t1 = 58123, а t2 = 01123)
t1 = tonumber(channel["STRFTIME(${EPOCH},0,%S%3q)"]:get())
while ringing == 1 do
app.waitforsilence(intervalLen,1,1.1) -- ждем окончания гудка (или перерыва в словах оператора)
t2 = tonumber(channel["STRFTIME(${EPOCH},0,%S%3q)"]:get())
if (t2 < t1) then t2 = t2 + 60000 end
if (t2 - t1 <= 950 or t2 - t1 >= 1050) then -- если звук длился <= 0.95 или >= 1.05 секунды
ringing = 0 -- значит оператор ответил, завершаем макрос
else
app.waitfornoise(intervalLen,1,4.1) -- если нет, то ждем следующего гудка (4 секунды)
t1 = tonumber(channel["STRFTIME(${EPOCH},0,%S%3q)"]:get())
if (t1 < t2) then t1 = t1 + 60000 end
if (t1 - t2 < 3950 or t1 - t2 >= 4050) then ringing = 0 end -- если следующий звук не через 4 секунды, то завершаем макрос
while t1 >= 60000 do t1 = t1 - 60000 end
end
end
return 1;
Проблема - в реальных условиях часто не распознается первый гудок, хотя все описанные условия соблюдаются (4 сек тишина, 1 сек - гудок, проверял в аудиоредакторе):
waitforsilence срабатывает через 100 - 700 мс, хотя должен срабатывать примерно через 1 секунду.
Увеличение интервала intervalLen не помогает.