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水木清华站∶精华区