Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

playfile.cpp

// Copyright (C) 2002 David Kerry.
//
// 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.
//
// As a special exception to the GNU General Public License, permission is
// granted for additional uses of the text contained in its release
// of Bayonne as noted here.
//
// This exception is that permission is hereby granted to link Bayonne
// with the Aculab telephony libraries to produce a executable image
// without requiring Aculab's libraries to be supplied in a free software
// license as long as each source file so linked contains this exclusion
// and the unaltered Aculab source files are made available.
//
// This exception does not however invalidate any other reasons why
// the resulting executable file might be covered by the GNU General
// public license or invalidate the licensing requirements of any
// other component or library.
//
// This exception applies only to the code released by OST under the
// name Bayonne.  If you copy code from other releases into a copy of
// Bayonne, as the General Public License permits, the exception does not
// apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own to Bayonne, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice, at which
// point the terms of your modification would be covered under the GPL
// as explicitly stated in "COPYING".


#include "driver.h"
#include <sys/ioctl.h>
#include <sys/stat.h>

#ifdef    CCXX_NAMESPACES
using namespace std;
namespace ost {
#endif

timeout_t AculabTrunk::StopPlayFile(void)
{
        char buffer[12];
      SM_REPLAY_ABORT_PARMS abort_parms;

      abort_parms.channel=dspChannel;
      abort_parms.offset=0;
      sm_replay_abort(&abort_parms);

        sprintf(buffer, "%ld", getTransfered());
        trunk->setSymbol(SYM_PLAYED, buffer);
      sprintf(buffer, "%ld", getPosition());
      trunk->setSymbol(SYM_OFFSET, buffer);
      close();

      return 0;
}

bool AculabTrunk::StartPlayFile(void)
{
      unsigned format, rate;
      SM_REPLAY_PARMS replay_parms;
      char *fmtconfig;
      int netformat = kSMDataFormat8KHzULawPCM;
      int rc;

      Trunk::flags.audio=true;

      fmtconfig=(char *)aculabivr.getNetFormat();
      
      rate = getSampleRate();
      switch(getEncoding())
      {
      case mulawAudio:
            /*The file will be played assuming that the data is
              in the format of the network.  If this is alaw, then 
              we will need to get the aculab resource to convert our
              file from mulaw to alaw */
              
            if(strcmp(fmtconfig, "alaw") == 0)
                  format = kSMDataFormat8KHzULawPCM;
            else
                  format = kSMDataFormat8KHzALawPCM;
            rate = 8000;
            break;
      case alawAudio:
            if(strcmp(fmtconfig, "ulaw") == 0)
                  format = kSMDataFormat8KHzALawPCM;
            else
                  format = kSMDataFormat8KHzULawPCM;
            format = netformat;
            rate = 8000;
            break;
      case pcm8Mono:
            format = kSMDataFormat8KHz8bitMono; /* Playback only */
            rate = 8000;
            break;
      case pcm16Mono:
            format = kSMDataFormat8KHz16bitMono; /* Playback only */
            rate = 8000;
            break;
      default:
            slog(Slog::levelError) << name << ": unsupported audio file format" << endl;
            return false;
      }

      if (rate != getSampleRate()) {
            slog(Slog::levelError) << name <<": format sample rate != file sample rate!"<<endl;
            return false;
      }

      replay_parms.channel=dspChannel;
      replay_parms.background=kSMNullChannelId;
      replay_parms.volume=0;
      replay_parms.agc=0;
      replay_parms.speed=0;
      replay_parms.type=format;
      replay_parms.data_length=0;

      slog(Slog::levelDebug)<<name<<": starting play of file '"<<filename<<"', bufsize="<<playaudiobufsize<<",format="<<format<<endl;

      rc=sm_replay_start(&replay_parms);
      if (rc != 0) {
            slog(Slog::levelError) <<name <<": cannot start replay of data: "<<rc<<endl;
            return false;
      }

      /* Force feed the first block to kick things into action */
      /* One isn't enough? */
      PlayNext();
      PlayNext();

      /*
       * The aculab driver will take care of notifying the
       * audio thread that there's work to do...
       */
       return true;
}

/*
 * Send next block of audio out to DSP
 */
bool AculabTrunk::PlayNext(void)
{
      SM_TS_DATA_PARMS ts_data;
      int len = 0;
      int rc;
      int offset = 0;

retry:
      /* Feed next frame/sample/block of data to Prosody */
      /* re-fill buffer */
      len=getBuffer(&playaudiobuffer + offset, playaudiobufsize - offset);
      if(len < (int)playaudiobufsize - offset && data.play.maxtime)
      {
            setPosition(0);
            offset += len;
            goto retry;
      }

      if(offset)
            len = offset;

      ts_data.channel=dspChannel;
      ts_data.data=playaudiobuffer;
      if (len == (int)playaudiobufsize) {
            ts_data.length=playaudiobufsize;
            rc=sm_put_replay_data(&ts_data);
      }
      else {
            ts_data.length=len;
            rc=sm_put_last_replay_data(&ts_data);
      }

      if (rc != 0) {
            slog(Slog::levelError) << "aculab(): cannot play audio data: "<<rc<<endl;
            return false;
      }

      return true;
}

/*
 * Retrieve next chunk of audio, the next file
 * in a sequence of files for example.
 */
char *AculabTrunk::getContinuation(void)
{
      char *fn;

      if((data.play.mode == PLAY_MODE_ONE) ||
         (data.play.mode == PLAY_MODE_TEMP)) {
                return NULL;
      }

retry:
      fn = getPlayfile();
      if(fn && (data.play.mode == PLAY_MODE_ANY)) {
            if(!canAccess(fn)) {
                  goto retry;
            }
      }
      return fn; 
}


#if 0
/*
 * Use the aculab 
 * This should really be done via the DSP's tone playing
 * capability instead of emulating a tone sample...
 *
 * To do that however, 
 */
timeout_t AculabTrunk::StartPlayTone()
{
      
      unsigned format, speed, rate, len, count = 0;
      SM_REPLAY_PARMS replay_parms;
      char *fmtconfig;
      int netformat;
      int rc;

      Trunk::flags.audio=true;

      fmtconfig=(char *)aculabivr.getNetFormat();
      if (strcmp(fmtconfig,"ulaw") == 0) {
            netformat = kSMDataFormat8KHzULawPCM;
      }
      else if (strcmp(fmtconfig,"alaw") == 0) {
            netformat = kSMDataFormat8KHzALawPCM;
      }

      rate = getSampleRate();
      switch(getEncoding())
      {
      case mulawAudio:
            format = netformat;
            rate = 8000;
            break;
      case alawAudio:
            format = netformat;
            rate = 8000;
            break;
      case pcm8Mono:
            format = kSMDataFormat8KHz8bitMono; /* Playback only */
            rate = 8000;
            break;
      case pcm16Mono:
            format = kSMDataFormat8KHz16bitMono; /* Playback only */
            rate = 8000;
            break;
      default:
            slog(Slog::levelError) <<name << ": unsupported audio file format" << endl;
            return false;
      }

      if (rate != getSampleRate()) {
            slog(Slog::levelError) << name <<": format sample rate != file sample rate!"<<endl;
            return false;
      }

      replay_parms.channel=dspChannel;
      replay_parms.background=kSMNullChannelId;
      replay_parms.volume=0;
      replay_parms.agc=0;
      replay_parms.speed=0;
      replay_parms.type=format;
      replay_parms.data_length=0;

      slog(Slog::levelDebug)<<name<<": starting play of file '"<<filename<<"', bufsize="<<playaudiobufsize<<",format="<<format<<endl;

      rc=sm_replay_start(&replay_parms);
      if (rc != 0) {
            slog(Slog::levelError) << name <<": cannot start replay of data: "<<rc<<endl;
            return false;
      }

      /* Force feed the first block to kick things into action */
      /* One isn't enough? */
      PlayNext();
      PlayNext();

      /*
       * The aculab driver will take care of notifying the
       * audio thread that there's work to do...
       */
}
timeout_t AculabTrunk::StopPlayTone(void)
{
}
#endif

#ifdef    CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index