BBS水木清华站∶精华区

发信人: wxb1 (ben), 信区: Linux        
标  题: [2/8] 语音数据机录/放音 
发信站: BBS 水木清华站 (Fri Jun 11 14:13:28 1999) 
 
 
以Linux实作 语音/传真/EMAIL/BBC 整合系统 
2.语音数据机录/放音 
 
        目前市面上的语音数据机,有九成以上皆使用Rockwell的晶片,因此以 
下的说明,皆针对此类的语音数据机,若您使用Zyxel等非Rockwell晶片的数据 
机,请参考其说明手册(英文的那一本),虽然AT Command 不同,但颇为类似 
!至於 Rockwell 的完整AT Command,或Voice Command,也可至其网站 
http://www.rockwell.com 抓取(我已忘了确实的 PATH)。 
 
VMCP 
        要能控制语音数据机传送或接收语音讯息,除了需了解语音部分的AT 
Command 之外,也需有方便的应用程式,帮您做串列埠或数据机的设定,同时也 
要能接收或传送语音资料。 VMCP (Voice Modem Control Program) 就是一个具 
此功能的软体,您可在Internet上自由的下载并使用,利用此程式可轻松设定个 
人电脑上的串列埠(如DTE速率)、传送AT Command 或二进位档至数据机, 亦可 
将数据机传来的资料转存至档案中、捕捉电话线另一端使用者的按键 (DTMF 
tones) 、送出数据机指令并根据指定的结束字串等待其回应等等。 
 
例如: 
   vmcp -z38400 -t8 -c"ATZ" -wOK 
其意义为设定串列埠之速度为38400,并送出ATZ的数据机重置指令,等待数据机 
回应"OK",若经过8秒仍无回应,则vmcp会有错误代码(100)回覆! 
 
   vmcp -c"AT#VRX" -W"\cCONNECT\r\n" -e -t10 -s"tone.log"  -x"#bcde" 
其意义为送出AT#VRX的语音指令(接收对方的语音或按键,此处主要是撷取按键) 
,-W(大写W,Skip String)略过数据机回应 CONNECT<CR><LF> (送出AT#VRX後, 
数据机的回应),等待对方按键,直到10秒钟Timeout,或遇到 -x 後所列的 
DLE-escaped 字元为止( -e 表示要处理DLE-escaped字元,所以有 -x 就必须 
有 -e),"#bcde"五字元各表示电话键盘上的"#"字符号、遇忙线音(Busy Tone) 
、语音转FAX( Calling Tone )、拨号音( Dial Tone )、或语音转Data传输( 
European Data Modem Calling Tone ), 并将对方按键(所有按键皆属 
DLE-escaped字元)存入tone.log 档案中。 因此若对方按12345#,此VMCP指令即 
会返回,并且在tone.log存有12345#。 
 
        由以上可知,虽然VMCP可接收按键,但是其是以指定的结尾字元来作为 
结束,而不能订定固定的长度(例如分机号码固定为三码,输入需为"123#"才可 
,无法仅键入三码),不过因VMCP有附原始程式码,仅需略作如下的修改,即可 
符合指定长度的要求: 
   ………… 
 
   /*  加入指定长度 L 的参数 */ 
while (( opt = getopt( argc, argv, "c:d:eghi:kl:L:o:qs:t:w:W:x:z:" ) ) != -1) 
      { 
      switch ( opt ) 
         { 
                        …………. 
 
         case 'L' : 
            keylen = atoi(optarg); break; 
                        ………….. 
         } 
      } 
 
        …………. 
 
/*----------------------------------------------------------------------*/ 
/* Write c to escape file, return TRUE if c is in esc_string.   */ 
/*----------------------------------------------------------------------*/ 
int out_esc(int c) 
   { 
                …………. 
 
      for ( i = 0 ; esc_string[i] != '\0' && esc_string[i] != (unsigned char) c  
; i++); 
      if ( esc_string[i] == '\0' ) 
                /* 加入此段 */ 
         if ( keylen && ( esc_num >= keylen ) ) { 
                ok_exit_code = -keylen; 
                return TRUE; 
         } else { 
                return FALSE; 
         } 
                /*  结束加入 */ 
      else 
                ………… 
   } 
 
如此当VMCP指定长度为n码时,若其EXIT CODE为 -n,表示对方确实为输入n码後 
返回! 
 
本地录音 
        目前在市面上买到的语襡cho "InHead:$InHead" 
        InputLen=2 
   else 
        InHead="" 
        InputLen=3 
   fi 
fi 
 
# 等待 User 输入代号 
$VMCP -c"$AT_VRX" -W"\cCONNECT\r\n" -e -t10 -s$tmpfile -L$InputLen -x"bcde" 
N=$? 
$VMCP -c"\c\n" -wVCON 
if [ $N -lt 253 ]; then 
        #256-3=253 ; 256-2=254 
        hang_up 
fi 
 
read InTail < $tmpfile 
UserID="$InHead$InTail" 
 
# Check User 
if [ -f ${MAINPATH}conf/$UserID.reg ]; then 
        # 寻找此 USER 是否有别人的留言 
        vocfiles=`$FIND ${MAINPATH}voc/${UserID}.* -printf " %p"` 
        PLAYFILE="${MAINPATH}voc/sys/select12.voc" 
        if [ `$ECHO -n $vocfiles | $WC -w` -gt "0" ];  then 
                # 若有的话,加上一段提示语"听留言请按3" 
                PLAYFILE="${PLAYFILE} ${MAINPATH}voc/sys/select3.voc" 
        Fi 
else 
                # 无此 user 
                play_message "${MAINPATH}voc/sys/UserErr.voc" "bcde" 
                hang_up 
fi 
 
# 播放提示语 "留言请按1;送传真过来请按2;(听留言请按3) 
for FILE in $PLAYFILE 
do 
        play_message $FILE "12345#bcde" 
        N=$? 
        if [ $N -gt 5 ]; then 
                hang_up 
        else 
            if [ $N -gt 0 ]; then 
                break 
            fi 
        fi 
 
done 
 
if [ $N -eq 0 ]; then 
   # N = 0 表示USER未中途按键,故需於此等待USER输入 
   $VMCP -c"$AT_VRX" -W"\cCONNECT\r\n" -e -t15 -s$tmpfile -x"12345bcde" 
   N=$? 
   # Stop listening 
   $VMCP -c"\c\n" -wVCON 
   if [ $N -gt 5 ]; then 
        hang_up 
   fi 
fi 
 
read info < $tmpfile 
# 判断USER的选择为何? 
case $info in 
     1) 
        # 对方要留言 
        # 写入此时USER及时间至记录档中,方便追踪或计算费用 
        logstr=`$DATE "+%D %T,Record Voc,User:$UserID"` 
        $ECHO $logstr >> $LOGFILE 
        # 播放指示语"听到哔声後请留言" 
        play_message "${MAINPATH}voc/sys/BeforeRecord.voc" "#bcde" 
        if [ $? -ne 0 ]; then 
                hang_up 
        fi 
        play_beep 
 
    # 留言档名根据UserID及此时时间命名 
    filename=`$DATE +$UserID.%d%H%M%S` 
        record_message "${MAINPATH}voc/$filename" "#bcde" 
#--------------执行 AMP 处理嘟嘟声及音量放大5倍---------------------- 
        $AMP ${MAINPATH}voc/${filename} ${MAINPATH}voc/${filename}.raw 5 
#---------------------------Voice --> EMAIL------------------- 
# 语音转EMAIL,参後篇论及"语音、传真、EMAIL的整合" 
#------------------------------Call BBC------------------- 
# 以BBC呼叫通知该USER,参後篇论及"呼叫BBC暨主动传真服务" 
        ;; 
     3) 
        # 回放该USER的留言 
        if [ `$ECHO -n $vocfiles | $WC -w` -gt "0" ]; then 
                # 需密码通过後才播放 
                chk_passwd 
        else 
            if [ `$ECHO -n $mail2voc | $WC -w` -gt "0" ];  then 
                        # 可能是由EMAIL转成的语音档,以後会再讨论 
                   chk_passwd 
            else 
                   hang_up 
            fi 
        fi 
 
        # 写入此时USER及时间至记录档中,方便追踪或计算费用 
        logstr=`$DATE "+%D %T,Play Voc,User:$UserID"` 
        $ECHO $logstr >> $LOGFILE 
 
        # 依序播放该USER所有留言 
        for FILE in $vocfiles; do 
          if [ -f $FILE ]; then 
                play_message $FILE "bcde" 
                if [ $? -ne 0 ]; then 
                        hang_up 
                fi 
          fi 
        done 
        # ------------EMAIL a Voice --------------------- 
        for FILE in $mail2voc; do 
           # 播放由EMAIL转成的语音档,参後篇论及"语音、传真、EMAIL的整合" 
        done 
 
        ;; 
   esac 
 
# Hang-up. 
hang_up 
 
结语 
 
        以上的讨论为在Linux上,使用Shell Script配合VMCP建立一简单的留 
言范例,皆下来会讨论在Linux上使用传真的一些作法,并会试著陆续探讨结合 
语音、传真、EMAIL及BBC,做讯息的交换与讯息的整合! 
 
撰文:朱先宇   1998/12/11 
EMAIL: hybj@ms1.hinet.net 
 
 
-- 
just a test 
 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.116.130.100] 

BBS水木清华站∶精华区