📄 play.cpp
字号:
// Copyright (C) 2000 Open Source Telecom Corporation.// // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.#include <config.h>#include <syslog.h>#include "server.h"#include "trunk.h"#include "aufile.h"Player::Player(Trunk *trk, char *path, long pos) :Service(trk), Thread((Semaphore *)NULL){ fd = -1; offset = pos; strcpy(pathname, path);}Player::~Player(){ Terminate(); if(fd > -1) close(fd); ioctl(device, PHONE_PLAY_STOP);}void Player::Initial(void){ int codec; int count = 0; int framing; int len; char *cp; int vol = trunk->getPlayVolume() * 10; char *ext = strrchr(pathname, '.'); AUFILE au; ioctl(device, PHONE_PLAY_VOLUME, vol); debug(9, "starting playback of %s", pathname); fd = open(pathname, O_RDONLY); setCancel(THREAD_CANCEL_IMMEDIATE); if(fd < 0) { syslog(LOG_ERR, "%s: cannot play", pathname); endService(); } if(!stricmp(ext, ".ul")) { codec = ULAW; framing = 20; len = 80; } if(!stricmp(ext, ".al")) { codec = ALAW; framing = 20; len = 80; } if(!stricmp(ext, ".au")) { if(::read(fd, &au, sizeof(au)) < sizeof(au)) endService(); switch(getaulong(au.encoding)) { case AU_ENCODING_MULAW: codec = ULAW; framing = 20; len = 80; break; case AU_ENCODING_ALAW: codec = ALAW; framing = 20; len = 80; } offset += getaulong(au.hdrsize); } cp = getkeylast(keyphone, "depth"); if(cp) ioctl(device, PHONE_PLAY_DEPTH, atoi(cp)); switch(trunk->getDriver()) { case ixj_driver: if(framing == 20) framing = 30; break; } while(framing != ioctl(device, PHONE_FRAME, framing) && count++ < 5) Sleep(20); if(count > 4) { syslog(LOG_ERR, "codec(%d) cannot set framing", codec); endService(); } if(ioctl(device, PHONE_PLAY_CODEC, codec)) { syslog(LOG_ERR, "codec(%d): unavailable", codec); endService(); } debug(9, "frame size %dms", framing); // compute actual buffer size of single frame I/O based on // selected impulse size of the frame frame = (framing / 10) * len; ioctl(device, PHONE_PLAY_START); lseek(fd, offset, SEEK_SET);}void Player::Run(void){ char buffer[frame]; // loose non-frame aligned data at end of file while(frame == ::read(fd, buffer, frame)) { if(frame != ::write(device, buffer, frame)) break; } endService();}void Trunk::Play(EventRecord *er){ int rtn; char pathname[128]; char *fn, *cp; switch(er->event) { case UM_EVENT_STOP_STATE: if(service) { delete service; service = NULL; } return scrExecute(); case UM_EVENT_ENTER_STATE: if(!offhook) { ioctl(device, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK); time(&starttime); offhook = true; } setDTMF(); // set up file name case PH_EVENT_SERVICE_ENDING: if(service) { delete service; service = NULL; } fn = getOption(NULL); if(!fn) break; if (strchr(fn, '/')) pathname[0] = 0; else { strcpy(pathname, getkeylast(keypaths, "prompts")); strcat(pathname, "/"); if(!strnicmp(fn, "*:", 2)) { ++fn; strcat(pathname, getLanguage()); } } strcat(pathname, fn); cp = strchr(pathname, ':'); if(cp) *cp = '/'; cp = strrchr(pathname, '/'); cp = strrchr(cp, '.'); if(!cp) strcat(pathname, ".ul"); debug(2, "pathname = %s",pathname); service = new Player(this, pathname, 0l); service->Start(); return; default: Default(er); return; } scrNext();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -