You can have sub macros <macros name="voicemail"><macro ...> and allow you to call it login@voicemail.
Change the sound-path to sound-prefix to make it constistant with the rest of freeswitch.
Also allow to set a sound-prefix to a macros, so you can override it for a specific file set.
You can set say-modules="en" or whatever in the <language section to define that say module to use.
<X-PRE-PROCESS cmd="include" data="directory/*.xml"/>
</section>
- <!-- phrases section (under development still) -->
- <section name="phrases" description="Speech Phrase Management">
- <macros>
- <X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
- <X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
- <X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
- <X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
- <X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
- </macros>
+ <!-- languages section (under development still) -->
+ <section name="languages" description="Language Management">
+ <X-PRE-PROCESS cmd="include" data="lang/de/*.xml"/>
+ <X-PRE-PROCESS cmd="include" data="lang/en/*.xml"/>
+ <X-PRE-PROCESS cmd="include" data="lang/fr/*.xml"/>
+ <X-PRE-PROCESS cmd="include" data="lang/ru/*.xml"/>
+ <X-PRE-PROCESS cmd="include" data="lang/he/*.xml"/>
</section>
</document>
<include>
- <language name="de" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
- <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
- <!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
- <X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
+ <language name="de" sound-prefix="/snds" tts-engine="cepstral" tts-voice="david">
+ <phrases>
+ <macros>
+ <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
+ <!--voicemail_de_tts is purely implemented with tts, we need a files based implementation too -->
+ <X-PRE-PROCESS cmd="include" data="vm/tts.xml"/>
+ </macros>
+ </phrases>
</language>
</include>
<include>
- <language name="en" sound-path="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
- <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
- <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
- <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
- <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
+ <language name="en" say-module="en" sound-prefix="$${sounds_dir}/en/us/callie" tts-engine="cepstral" tts-voice="callie">
+ <phrases>
+ <macros>
+ <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
+ <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
+ <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
+ <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
+ </macros>
+ </phrases>
</language>
</include>
<include>
- <language name="fr" sound-path="/snds" tts-engine="cepstral" tts-voice="david">
- <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
- <!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
- <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
- <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
+ <language name="fr" say-module="fr" sound-prefix="$${sounds_dir}/fr/ca/june" tts-engine="cepstral" tts-voice="david">
+ <phrases>
+ <macros>
+ <X-PRE-PROCESS cmd="include" data="demo/demo.xml"/>
+ <!--voicemail_fr_tts is purely implemented with tts, we need a files based implementation too -->
+ <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
+ <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/> <!-- dir/tts.xml if you want to use tts and have cepstral -->
+ </macros>
+ </phrases>
</language>
</include>
<include>
- <language name="he" sound-path="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
- <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
- <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
- <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
+ <language name="he" sound-prefix="$${sounds_dir}/he/daniel" tts-engine="cepstral" tts-voice="daniel">
+ <phrases>
+ <macros>
+ <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
+ <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/>
+ <X-PRE-PROCESS cmd="include" data="dir/sounds.xml"/>
+ </macros>
+ </phrases>
</language>
</include>
<?xml version="1.0" encoding="utf-8"?>
<!--тестовые файлы Вы звуковые файлы можно взять тут svn co http://svn.freeswitch.ru/bbv/mod_say_ru/ru/ -->
<include>
- <language name="ru" sound-path="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
- <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
- <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
- <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
+ <language name="ru" sound-prefix="$${sounds_dir}/ru/RU/elena" tts-engine="cepstral" tts-voice="elena">
+ <phrases>
+ <macros>
+ <X-PRE-PROCESS cmd="include" data="demo/*.xml"/> <!-- Note: this now grabs whole subdir, previously grabbed only demo.xml -->
+ <!--voicemail_en_tts is purely implemented with tts, we have the files based one that is the default. -->
+ <X-PRE-PROCESS cmd="include" data="vm/sounds.xml"/> <!-- vm/tts.xml if you want to use tts and have cepstral -->
+ </macros>
+ </phrases>
</language>
</include>
SWITCH_DECLARE(int) switch_xml_std_datetime_check(switch_xml_t xcond);
+SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language);
+
SWITCH_END_EXTERN_C
///\}
#endif // _SWITCH_XML_H
<menus>
<menu name="std_authenticate">
<phrases>
- <phrase name="fail_auth" value="protovm_fail_auth" />
+ <phrase name="fail_auth" value="fail_auth@protovm" />
</phrases>
<keys>
</keys>
<menu name="std_authenticate_ask_user">
<phrases>
- <phrase name="instructions" value="protovm_enter_id" />
+ <phrase name="instructions" value="enter_id@protovm" />
</phrases>
<keys>
<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
<menu name="std_authenticate_ask_password">
<phrases>
- <phrase name="instructions" value="protovm_enter_pass" />
+ <phrase name="instructions" value="enter_pass@protovm" />
</phrases>
<keys>
<key dtmf="#" action="ivrengine:terminate_entry" variable="VM-Key-Terminator" /> <!-- TODO Make the ivrengine: parsed and the key configurable -->
<menu name="std_navigator">
<phrases>
- <phrase name="msg_count" value="protovm_message_count" />
- <phrase name="say_date" value="protovm_say_date_event" />
- <phrase name="say_msg_number" value="protovm_say_message_number" />
- <phrase name="menu_options" value="protovm_listen_file_check" />
- <phrase name="ack" value="protovm_ack" />
- <phrase name="play_message" value="protovm_play_message" />
+ <phrase name="msg_count" value="message_count@protovm" />
+ <phrase name="say_date" value="say_date_event@protovm" />
+ <phrase name="say_msg_number" value="say_message_number@protovm" />
+ <phrase name="menu_options" value="listen_file_check@protovm" />
+ <phrase name="ack" value="ack@protovm" />
+ <phrase name="play_message" value="play_message@protovm" />
</phrases>
<keys>
<key dtmf="1" action="skip_intro" variable="VM-Key-Main-Listen-File" />
<menu name="std_preference">
<phrases>
- <phrase name="menu_options" value="protovm_config_menu" />
+ <phrase name="menu_options" value="config_menu@protovm" />
</phrases>
<keys>
<key dtmf="1" action="menu:std_record_greeting_with_slot" variable="VM-Key-Record-Greeting" />
<menu name="std_record_greeting">
<phrases>
- <phrase name="instructions" value="voicemail_record_greeting" />
- <phrase name="play_recording" value="protovm_play_recording" />
- <phrase name="menu_options" value="protovm_record_file_check" />
+ <phrase name="instructions" value="record_greeting@protovm" />
+ <phrase name="play_recording" value="play_recording@protovm" />
+ <phrase name="menu_options" value="record_file_check@protovm" />
</phrases>
<keys>
<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
<menu name="std_record_name">
<phrases>
- <phrase name="instructions" value="protovm_record_name" />
- <phrase name="play_recording" value="protovm_play_recording" />
- <phrase name="menu_options" value="protovm_record_file_check" />
+ <phrase name="instructions" value="record_name@protovm" />
+ <phrase name="play_recording" value="play_recording@protovm" />
+ <phrase name="menu_options" value="record_file_check@protovm" />
</phrases>
<keys>
<key dtmf="1" action="listen" variable="VM-Key-Listen-File" />
<menu name="std_select_greeting_slot">
<phrases>
- <phrase name="instructions" value="protovm_choose_greeting" />
- <phrase name="invalid_slot" value="protovm_choose_greeting_fail" />
- <phrase name="selected_slot" value="protovm_greeting_selected" />
+ <phrase name="instructions" value="choose_greeting@protovm" />
+ <phrase name="invalid_slot" value="choose_greeting_fail@protovm" />
+ <phrase name="selected_slot" value="greeting_selected@protovm" />
</phrases>
<keys>
</keys>
<menu name="std_record_greeting_with_slot">
<phrases>
- <phrase name="instructions" value="protovm_choose_greeting" />
+ <phrase name="instructions" value="choose_greeting@protovm" />
</phrases>
<keys>
</keys>
<menu name="std_set_password">
<phrases>
- <phrase name="instructions" value="protovm_enter_pass" />
+ <phrase name="instructions" value="enter_pass@protovm" />
</phrases>
<keys>
</keys>
<include><!--This line will be ignored it's here to validate the xml and is optional -->
- <macro name="protovm_press_key">
- <input pattern="^(.*):(.*)$">
- <match>
- <action function="play-file" data="$2"/>
- <action function="play-file" data="voicemail/vm-press.wav"/>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_plurial_msg">
- <input pattern="^[01]:(.*):(.*)$" break_on_match="true">
- <match>
- <action function="play-file" data="$1"/>
- </match>
- </input>
- <input pattern="^.*:(.*):(.*)$" break_on_match="true">
- <match>
- <action function="play-file" data="$2"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_enter_id">
- <input pattern="(.+)">
- <match>
- <action function="play-file" data="voicemail/vm-enter_id.wav"/>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- </match>
- <nomatch>
- <action function="play-file" data="voicemail/vm-enter_id.wav"/>
- <action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
- </nomatch>
- </input>
- </macro>
-
-
- <macro name="protovm_enter_pass">
- <input pattern="(.+)">
- <match>
- <action function="play-file" data="voicemail/vm-enter_pass.wav"/>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- </match>
- <nomatch>
- <action function="play-file" data="voicemail/vm-enter_pass.wav"/>
- <action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
- </nomatch>
-
- </input>
- </macro>
-
- <macro name="protovm_fail_auth">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-fail_auth.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_hello">
- <input>
- <match>
- <!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
- </match>
- </input>
- </macro>
-
- <macro name="protovm_goodbye">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-goodbye.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_abort">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-abort.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_message_count">
- <input field="${VM-Total-New-Urgent-Messages}" pattern="^(0)$">
- <nomatch>
- <action function="play-file" data="voicemail/vm-you_have.wav"/>
- <action function="say" data="${VM-Total-New-Urgent-Messages}" method="pronounced" type="items"/>
- <action function="play-file" data="voicemail/vm-urgent-new.wav"/>
- <action function="phrase" phrase="voicemail_plurial_msg" data="${VM-Total-New-Urgent-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
- </nomatch>
- </input>
- <input field="${VM-Total-New-Messages}" pattern="^(\d+)$">
- <match>
- <action function="play-file" data="voicemail/vm-you_have.wav"/>
- <action function="say" data="${VM-Total-New-Messages}" method="pronounced" type="items"/>
- <action function="play-file" data="voicemail/vm-new.wav"/>
- <action function="phrase" phrase="voicemail_plurial_msg" data="${VM-Total-New-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
- </match>
- </input>
- <input field="${VM-Total-Saved-Messages}" pattern="^(0)$">
- <nomatch>
- <action function="play-file" data="currency/and.wav"/>
- <action function="say" data="${VM-Total-Saved-Messages}" method="pronounced" type="items"/>
- <action function="play-file" data="voicemail/vm-saved.wav"/>
- <action function="phrase" phrase="voicemail_plurial_msg" data="${VM-Total-Saved-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
- </nomatch>
- </input>
- </macro>
-
- <macro name="protovm_menu">
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Play-New-Messages}:voicemail/vm-listen_new.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Play-Saved-Messages}:voicemail/vm-listen_saved.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Config-Menu}:voicemail/vm-advanced.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Terminator}:voicemail/vm-to_exit.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_config_menu">
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Record-Greeting}:voicemail/vm-to_record_greeting.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Choose-Greeting}:voicemail/vm-choose_greeting.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Record-Name}:voicemail/vm-record_name2.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Change-Password}:voicemail/vm-change_password.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Menu}:voicemail/vm-main_menu.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_record_name">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-record_name1.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_record_file_check">
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Save-File}:voicemail/vm-save_recording.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Record-File}:voicemail/vm-rerecord.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_record_urgent_check">
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Urgent}:voicemail/vm-mark-urgent.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Terminator}:voicemail/vm-continue.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_forward_prepend">
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Forward}:voicemail/vm-send_message_now.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_forward_message_enter_extension">
- <input pattern="^([0-9#*])$">
- <match>
- <action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
- <action function="play-file" data="voicemail/vm-followed_by.wav"/>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_invalid_extension">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_listen_file_check">
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Next-Msg}:voicemail/vm-for_next_msg.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Save-File}:voicemail/vm-save_recording.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Delete-File}:voicemail/vm-delete_recording.wav"/>
- </match>
- </input>
- <input field="${VM-Message-Email}" pattern="^$">
- <nomatch>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Email}:voicemail/vm-forward_to_email.wav"/>
- </nomatch>
- </input>
- <input>
- <match>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Callback}:voicemail/vm-return_call.wav"/>
- <action function="phrase" phrase="voicemail_press_key" data="${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_choose_greeting">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_choose_greeting_fail">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_record_greeting">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-record_greeting.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_record_message">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-record_message.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_greeting_selected">
- <input pattern="^(\d+)$">
- <match>
- <action function="play-file" data="voicemail/vm-greeting.wav"/>
- <action function="say" data="$1" method="pronounced" type="items"/>
- <action function="play-file" data="voicemail/vm-selected.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_play_greeting">
- <input pattern="^(.*)$">
- <match>
- <action function="play-file" data="voicemail/vm-person.wav"/>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- <action function="play-file" data="voicemail/vm-not_available.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_say_number">
- <input pattern="^(\d+)$">
- <match>
- <action function="say" data="$1" method="pronounced" type="items"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_say_message_number">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-${VM-Message-Type}.wav"/>
- <action function="play-file" data="voicemail/vm-message_number.wav"/>
- <action function="say" data="${VM-Message-Number}" method="pronounced" type="items"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_say_phone_number">
- <input pattern="^(.*)$">
- <match>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_say_name">
- <input pattern="^(.*)$">
- <match>
- <action function="say" data="$1" method="pronounced" type="name_spelled"/>
- </match>
- </input>
- </macro>
- <!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
- <macro name="protovm_ack">
- <input pattern="^(too-small)$">
- <match>
- <action function="play-file" data="voicemail/vm-too-small.wav"/>
- </match>
- </input>
- <input pattern="^(undeleted)$">
- <match>
- <action function="play-file" data="voicemail/vm-message.wav"/>
- <action function="play-file" data="voicemail/vm-$1.wav"/>
- </match>
- </input>
- <input pattern="^(deleted)$">
- <match>
- <action function="play-file" data="voicemail/vm-message.wav"/>
- <action function="play-file" data="voicemail/vm-$1.wav"/>
- </match>
- </input>
- <input pattern="^(saved)$">
- <match>
- <action function="play-file" data="voicemail/vm-message.wav"/>
- <action function="play-file" data="voicemail/vm-$1.wav"/>
- </match>
- </input>
- <input pattern="^(emailed)$">
- <match>
- <action function="play-file" data="voicemail/vm-message.wav"/>
- <action function="play-file" data="voicemail/vm-$1.wav"/>
- </match>
- </input>
- <input pattern="^(marked-urgent)$">
- <match>
- <action function="play-file" data="voicemail/vm-message.wav"/>
- <action function="play-file" data="voicemail/vm-$1.wav"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_say_date">
- <input pattern="^(.*)$">
- <match>
- <action function="say" data="$1" method="pronounced" type="short_date_time"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_say_date_event">
- <input>
- <match>
- <action function="say" data="${VM-Message-Received-Epoch}" method="pronounced" type="short_date_time"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_play_message">
- <input>
- <match>
- <action function="play-file" data="${VM-Message-File-Path}"/>
- </match>
- </input>
- </macro>
-
- <macro name="protovm_play_recording">
- <input>
- <match>
- <action function="play-file" data="${VM-Record-File-Path}"/>
- </match>
- </input>
- </macro>
+ <macros name="protovm" sound-prefix="$${sounds_dir}/fr/ca/june">
+ <macro name="press_key">
+ <input pattern="^(.*):(.*)$">
+ <match>
+ <action function="play-file" data="$2"/>
+ <action function="play-file" data="voicemail/vm-press.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
- <macro name="protovm_disk_quota_exceeded">
- <input>
- <match>
- <action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
- </match>
- </input>
- </macro>
-
+ <macro name="plurial_msg">
+ <input pattern="^[01]:(.*):(.*)$" break_on_match="true">
+ <match>
+ <action function="play-file" data="$1"/>
+ </match>
+ </input>
+ <input pattern="^.*:(.*):(.*)$" break_on_match="true">
+ <match>
+ <action function="play-file" data="$2"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="enter_id">
+ <input pattern="(.+)">
+ <match>
+ <action function="play-file" data="voicemail/vm-enter_id.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ <nomatch>
+ <action function="play-file" data="voicemail/vm-enter_id.wav"/>
+ <action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
+ </nomatch>
+ </input>
+ </macro>
+
+
+ <macro name="enter_pass">
+ <input pattern="(.+)">
+ <match>
+ <action function="play-file" data="voicemail/vm-enter_pass.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ <nomatch>
+ <action function="play-file" data="voicemail/vm-enter_pass.wav"/>
+ <action function="say" data="${VM-Key-Terminator}" method="pronounced" type="name_spelled"/>
+ </nomatch>
+
+ </input>
+ </macro>
+
+ <macro name="fail_auth">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-fail_auth.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="hello">
+ <input>
+ <match>
+ <!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
+ </match>
+ </input>
+ </macro>
+
+ <macro name="goodbye">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-goodbye.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="abort">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-abort.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="message_count">
+ <input field="${VM-Total-New-Urgent-Messages}" pattern="^(0)$">
+ <nomatch>
+ <action function="play-file" data="voicemail/vm-you_have.wav"/>
+ <action function="say" data="${VM-Total-New-Urgent-Messages}" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-urgent-new.wav"/>
+ <action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-New-Urgent-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
+ </nomatch>
+ </input>
+ <input field="${VM-Total-New-Messages}" pattern="^(\d+)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-you_have.wav"/>
+ <action function="say" data="${VM-Total-New-Messages}" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-new.wav"/>
+ <action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-New-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
+ </match>
+ </input>
+ <input field="${VM-Total-Saved-Messages}" pattern="^(0)$">
+ <nomatch>
+ <action function="play-file" data="currency/and.wav"/>
+ <action function="say" data="${VM-Total-Saved-Messages}" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-saved.wav"/>
+ <action function="phrase" phrase="plurial_msg@protovm" data="${VM-Total-Saved-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"/>
+ </nomatch>
+ </input>
+ </macro>
+
+ <macro name="menu">
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Play-New-Messages}:voicemail/vm-listen_new.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Play-Saved-Messages}:voicemail/vm-listen_saved.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Config-Menu}:voicemail/vm-advanced.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Terminator}:voicemail/vm-to_exit.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="config_menu">
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-Greeting}:voicemail/vm-to_record_greeting.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Choose-Greeting}:voicemail/vm-choose_greeting.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-Name}:voicemail/vm-record_name2.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Change-Password}:voicemail/vm-change_password.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Menu}:voicemail/vm-main_menu.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="record_name">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-record_name1.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="record_file_check">
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Save-File}:voicemail/vm-save_recording.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Record-File}:voicemail/vm-rerecord.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="record_urgent_check">
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Urgent}:voicemail/vm-mark-urgent.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Terminator}:voicemail/vm-continue.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="forward_prepend">
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Forward}:voicemail/vm-send_message_now.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="forward_message_enter_extension">
+ <input pattern="^([0-9#*])$">
+ <match>
+ <action function="play-file" data="voicemail/vm-forward_enter_ext.wav"/>
+ <action function="play-file" data="voicemail/vm-followed_by.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="invalid_extension">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-that_was_an_invalid_ext.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="listen_file_check">
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Next-Msg}:voicemail/vm-for_next_msg.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Listen-File}:voicemail/vm-listen_to_recording.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Save-File}:voicemail/vm-save_recording.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Delete-File}:voicemail/vm-delete_recording.wav"/>
+ </match>
+ </input>
+ <input field="${VM-Message-Email}" pattern="^$">
+ <nomatch>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Email}:voicemail/vm-forward_to_email.wav"/>
+ </nomatch>
+ </input>
+ <input>
+ <match>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Callback}:voicemail/vm-return_call.wav"/>
+ <action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="choose_greeting">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-choose_greeting_choose.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="choose_greeting_fail">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-choose_greeting_fail.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="record_greeting">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-record_greeting.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="record_message">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-record_message.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="greeting_selected">
+ <input pattern="^(\d+)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-greeting.wav"/>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ <action function="play-file" data="voicemail/vm-selected.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="play_greeting">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-person.wav"/>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ <action function="play-file" data="voicemail/vm-not_available.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="say_number">
+ <input pattern="^(\d+)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="items"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="say_message_number">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-${VM-Message-Type}.wav"/>
+ <action function="play-file" data="voicemail/vm-message_number.wav"/>
+ <action function="say" data="${VM-Message-Number}" method="pronounced" type="items"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="say_phone_number">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="say_name">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="name_spelled"/>
+ </match>
+ </input>
+ </macro>
+ <!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
+ <macro name="ack">
+ <input pattern="^(too-small)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-too-small.wav"/>
+ </match>
+ </input>
+ <input pattern="^(undeleted)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ <input pattern="^(deleted)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ <input pattern="^(saved)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ <input pattern="^(emailed)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ <input pattern="^(marked-urgent)$">
+ <match>
+ <action function="play-file" data="voicemail/vm-message.wav"/>
+ <action function="play-file" data="voicemail/vm-$1.wav"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="say_date">
+ <input pattern="^(.*)$">
+ <match>
+ <action function="say" data="$1" method="pronounced" type="short_date_time"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="say_date_event">
+ <input>
+ <match>
+ <action function="say" data="${VM-Message-Received-Epoch}" method="pronounced" type="short_date_time"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="play_message">
+ <input>
+ <match>
+ <action function="play-file" data="${VM-Message-File-Path}"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="play_recording">
+ <input>
+ <match>
+ <action function="play-file" data="${VM-Record-File-Path}"/>
+ </match>
+ </input>
+ </macro>
+
+ <macro name="disk_quota_exceeded">
+ <input>
+ <match>
+ <action function="play-file" data="voicemail/vm-mailbox_full.wav"/>
+ </match>
+ </input>
+ </macro>
+ </macros>
</include><!--This line will be ignored it's here to validate the xml and is optional -->
XML_LDAP_CONFIG = 0,
XML_LDAP_DIRECTORY,
XML_LDAP_DIALPLAN,
- XML_LDAP_PHRASE
+ XML_LDAP_PHRASE,
+ XML_LDAP_LANGUAGE
} xml_ldap_query_type_t;
SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load);
query_type = XML_LDAP_DIALPLAN;
} else if (!strcmp(section, "phrases")) {
query_type = XML_LDAP_PHRASE;
+ } else if (!strcmp(section, "languages")) {
+ query_type = XML_LDAP_LANGUAGE;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n");
return NULL;
case XML_LDAP_DIALPLAN:
case XML_LDAP_PHRASE:
+ case XML_LDAP_LANGUAGE:
break;
}
}
break;
case XML_LDAP_PHRASE:
+ case XML_LDAP_LANGUAGE:
break;
}
} else {
* Matt Klein <mklein@nmedia.net>
* Michael Jerris <mike@jerris.com>
* Ken Rice <krice at suspicious dot org>
+ * Marc Olivier Chouinard <mochouinard@moctel.com>
*
* switch_ivr.c -- IVR Library
*
switch_say_interface_t *si;
switch_channel_t *channel;
switch_status_t status = SWITCH_STATUS_FALSE;
- const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *lname = NULL, *sound_path = NULL;
+ const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
switch_event_t *hint_data;
- switch_xml_t cfg, xml = NULL, language, macros;
+ switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
char *p;
switch_assert(session);
}
if (module_name) {
+ char *p;
p = switch_core_session_strdup(session, module_name);
module_name = p;
switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
switch_channel_event_set_data(channel, hint_data);
- if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
+ if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) {
goto done;
}
- if (!(macros = switch_xml_child(cfg, "macros"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
- goto done;
+ if ((p = (char *) switch_xml_attr(language, "say-module"))) {
+ module_name = switch_core_session_strdup(session, p);
+ } else if ((p = (char *) switch_xml_attr(language, "module"))) {
+ module_name = switch_core_session_strdup(session, p);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
+ } else {
+ module_name = chan_lang;
}
- if (!(language = switch_xml_child(macros, "language"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
- goto done;
+ if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
+ if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
+ sound_path = (char *) switch_xml_attr(language, "sound_path");
+ }
}
- while (language) {
- if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
- const char *tmp;
-
- if ((tmp = switch_xml_attr(language, "module"))) {
- module_name = tmp;
+ if (channel) {
+ const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
+ if (!switch_true(p)) {
+ save_path = switch_channel_get_variable(channel, "sound_prefix");
+ if (sound_path) {
+ switch_channel_set_variable(channel, "sound_prefix", sound_path);
}
- break;
}
- language = language->next;
- }
-
- if (!language) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
- goto done;
}
- if (!module_name) {
- module_name = chan_lang;
- }
-
- if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
- sound_path = (char *) switch_xml_attr(language, "sound_path");
- }
-
- save_path = switch_channel_get_variable(channel, "sound_prefix");
-
- if (sound_path) {
- switch_channel_set_variable(channel, "sound_prefix", sound_path);
- p = switch_core_session_strdup(session, sound_path);
- sound_path = p;
- }
-
- if (xml) {
- switch_xml_free(xml);
- }
-
if ((si = switch_loadable_module_get_say_interface(module_name))) {
/* should go back and proto all the say mods to const.... */
switch_say_args_t say_args = {0};
if (save_path) {
switch_channel_set_variable(channel, "sound_prefix", save_path);
}
-
+
+ if (xml) {
+ switch_xml_free(xml);
+ }
+
return status;
}
switch_say_interface_t *si;
switch_channel_t *channel = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
- const char *save_path = NULL, *chan_lang = NULL, *lname = NULL, *sound_path = NULL;
+ const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
switch_event_t *hint_data;
- switch_xml_t cfg, xml = NULL, language, macros;
+ switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
if (session) {
channel = switch_core_session_get_channel(session);
switch_channel_event_set_data(channel, hint_data);
}
- if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
- goto done;
- }
-
- if (!(macros = switch_xml_child(cfg, "macros"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
+ if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) {
goto done;
}
- if (!(language = switch_xml_child(macros, "language"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
- goto done;
- }
-
- while (language) {
- if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
- const char *tmp;
-
- if ((tmp = switch_xml_attr(language, "module"))) {
- module_name = tmp;
- }
- break;
- }
- language = language->next;
- }
-
- if (!language) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
- goto done;
- }
-
- if (!module_name) {
+ if ((module_name = switch_xml_attr(language, "say-module"))) {
+ } else if ((module_name = switch_xml_attr(language, "module"))) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
+ } else {
module_name = chan_lang;
}
- if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
- sound_path = (char *) switch_xml_attr(language, "sound_path");
+ if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
+ if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
+ sound_path = (char *) switch_xml_attr(language, "sound_path");
+ }
}
if (channel) {
- save_path = switch_channel_get_variable(channel, "sound_prefix");
- }
-
- if (sound_path && channel) {
- switch_channel_set_variable(channel, "sound_prefix", sound_path);
+ const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
+ if (!switch_true(p)) {
+ save_path = switch_channel_get_variable(channel, "sound_prefix");
+ if (sound_path) {
+ switch_channel_set_variable(channel, "sound_prefix", sound_path);
+ }
+ }
}
if ((si = switch_loadable_module_get_say_interface(module_name))) {
* Neal Horman <neal at wanlink dot com>
* Matt Klein <mklein@nmedia.net>
* Michael Jerris <mike@jerris.com>
+ * Marc Olivier Chouinard <mochouinard@moctel.com>
*
* switch_ivr_play_say.c -- IVR Library (functions to play or say audio)
*
switch_input_args_t *args)
{
switch_event_t *hint_data;
- switch_xml_t cfg, xml = NULL, language, macros, macro, input, action;
- char *lname = NULL, *mname = NULL;
+ switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action;
switch_status_t status = SWITCH_STATUS_GENERR;
const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
const char *module_name = NULL, *chan_lang = NULL;
int matches = 0;
const char *pause_val;
int pause = 100;
+ const char *group_macro_name = NULL;
+ const char *local_macro_name = macro_name;
+ switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
+ switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
if (!macro_name) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
chan_lang = lang;
}
- module_name = chan_lang;
-
switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(hint_data);
}
switch_channel_event_set_data(channel, hint_data);
- if (switch_xml_locate("phrases", NULL, NULL, NULL, &xml, &cfg, hint_data, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Open of phrases failed.\n");
+ if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, ¯os, chan_lang) != SWITCH_STATUS_SUCCESS) {
goto done;
}
- if (!(macros = switch_xml_child(cfg, "macros"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros tag.\n");
- goto done;
- }
-
- if (!(language = switch_xml_child(macros, "language"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language tag.\n");
- goto done;
+ if ((module_name = switch_xml_attr(language, "say-module"))) {
+ } else if ((module_name = switch_xml_attr(language, "module"))) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n");
+ } else {
+ module_name = chan_lang;
}
- while (language) {
- if ((lname = (char *) switch_xml_attr(language, "name")) && !strcasecmp(lname, chan_lang)) {
- const char *tmp;
-
- if ((tmp = switch_xml_attr(language, "module"))) {
- module_name = tmp;
- }
- break;
+ if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
+ if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
+ sound_path = (char *) switch_xml_attr(language, "sound_path");
}
- language = language->next;
- }
-
- if (!language) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find language %s.\n", chan_lang);
- goto done;
- }
-
- if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
- sound_path = (char *) switch_xml_attr(language, "sound_path");
}
if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) {
tts_voice = (char *) switch_xml_attr(language, "tts_voice");
}
- if (sound_path) {
+ /* If we use the new structure, check for a group name */
+ if (language != macros) {
char *p;
- old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
- p = switch_core_session_strdup(session, old_sound_prefix);
- old_sound_prefix = p;
- switch_channel_set_variable(channel, "sound_prefix", sound_path);
- }
+ char *macro_name_dup = switch_core_session_strdup(session, macro_name);
+ const char *group_sound_path;
+ const char *sound_prefix_enforced_str;
- if (!(macro = switch_xml_child(language, "macro"))) {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any macro tags.\n");
- goto done;
- }
+ if ((p = strchr(macro_name_dup, '@'))) {
+ *p++ = '\0';
+ local_macro_name = macro_name_dup;
+ group_macro_name = p;
- while (macro) {
- if ((mname = (char *) switch_xml_attr(macro, "name")) && !strcasecmp(mname, macro_name)) {
- break;
+ if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name);
+ goto done;
+ }
}
- macro = macro->next;
+ /* Support override of certain language attribute */
+ if ((group_sound_path = (char *) switch_xml_attr(macros, "sound-prefix")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound-path")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound_path"))) {
+ sound_path = group_sound_path;
+ }
+
+ if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced"))
+ && (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) {
+ switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str);
+ }
+
}
- if (!macro) {
+ if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
goto done;
}
+ if (sound_path && sound_prefix_enforced == SWITCH_FALSE) {
+ char *p;
+ old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
+ p = switch_core_session_strdup(session, old_sound_prefix);
+ old_sound_prefix = p;
+ switch_channel_set_variable(channel, "sound_prefix", sound_path);
+ }
+
if ((pause_val = switch_xml_attr(macro, "pause"))) {
int tmp = atoi(pause_val);
if (tmp >= 0) {
if (old_sound_prefix) {
switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
}
+ if (local_sound_prefix_enforced == SWITCH_TRUE) {
+ switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
+ }
+
if (xml) {
switch_xml_free(xml);
}
*
* Anthony Minessale II <anthm@freeswitch.org>
* Simon Capper <skyjunky@sbcglobal.net>
- *
+ * Marc Olivier Chouinard <mochouinard@moctel.com>
*
* switch_xml.c -- XML PARSER
*
return time_match;
}
+SWITCH_DECLARE(switch_status_t) switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language) {
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (switch_xml_locate("languages", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
+ switch_xml_t sub_macros;
+
+ if (switch_xml_locate("phrases", NULL, NULL, NULL, root, node, params, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of languages and phrases failed.\n");
+ goto done;
+ }
+ if (!(sub_macros = switch_xml_child(*node, "macros"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
+ switch_xml_free(*root);
+ *root = NULL;
+ *node = NULL;
+ goto done;
+ }
+ if (!(*language = switch_xml_find_child(sub_macros, "language", "name", str_language))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
+ switch_xml_free(*root);
+ *root = NULL;
+ *node = NULL;
+ goto done;
+ }
+ *macros = *language;
+ } else {
+ if (!(*language = switch_xml_find_child(*node, "language", "name", str_language))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find language %s.\n", str_language);
+ switch_xml_free(*root);
+ *root = NULL;
+ goto done;
+ }
+ if (!(*phrases = switch_xml_child(*language, "phrases"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find phrases tag.\n");
+ switch_xml_free(*root);
+ *root = NULL;
+ *node = NULL;
+ *language = NULL;
+ goto done;
+ }
+
+ if (!(*macros = switch_xml_child(*phrases, "macros"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find macros tag.\n");
+ switch_xml_free(*root);
+ *root = NULL;
+ *node = NULL;
+ *language = NULL;
+ *phrases = NULL;
+ goto done;
+ }
+ }
+ status = SWITCH_STATUS_SUCCESS;
+
+done:
+ return status;
+}
#ifdef WIN32
/*