Hi Stefan
Is this what you are looking for?
Cheers
Jason
On Tue, Jun 10, 2008 at 4:50 PM, Stefan Sayer <[EMAIL PROTECTED]>
wrote:
> Hello,
>
>
> o Jason Penton [06/10/08 16:44]:
>
>> Hi Stefan
>>
>> Just a note to the list.
>>
>> This worked perfectly - all I had to do was add the getters and setters
>> for autorewind to IvrAudio.cpp
>>
> for convenience can you send a patch made with
> $ svn diff
> ?
>
> thanks
> Stefan
>
>
>> Thanks
>> Cheers
>> Jason
>>
>>
>> On Fri, May 30, 2008 at 12:36 AM, Stefan Sayer <[EMAIL PROTECTED]<mailto:
>> [EMAIL PROTECTED]>> wrote:
>>
>> Hello Jason,
>>
>> o Jason Penton [05/29/08 18:01]:
>>
>> Hi All
>>
>> I noticed a problem today when trying to enqueue audio files via
>> python:
>>
>> basically if I queue the same file more than once, the second
>> instance does not actually play. For example:
>>
>> for example
>>
>> (line 1) self.enqueue(self.voice_lib['yes'],None)
>> (line 2) self.enqueue(self.voice_lib['no'],None)
>> (line 3) self.enqueue(self.voice_lib['yes'],None)
>>
>> everything works fine, except line 3 never plays the second
>> 'yes' file.
>>
>> yes, the file is already at its end.
>>
>>
>> It does however work if I flush the q before line 3 but surely the
>> above should work??????
>>
>> on investigation into the source code it appears that there is a
>> problem in AmPlaylist.cpp where the initial audio file is never
>> 'rewound' to the beginning. The result is that the second play
>> of that file doesnt have any data as it is at the end of the file.
>>
>> if you use another IvrAudioFile object, that would work as well.
>>
>>
>>
>> I managed to solve this with the following code, but not sure if
>> there is a better solution. Possibly we need a variable to flag
>> if a file that has already been played within the queue so it
>> can be rewound instead of forcing a rewind for every file (which
>> is unnecessary)
>>
>> hm, what I do not like that much about this way to fix the problem
>> is that it is not possible to not have the AmAudio rewound before it
>> is played. If you for example are playing half of a file, then you
>> get to put something different in the queue, and then re-enqueue the
>> first file, it is played from the beginning.
>>
>> so, what about a property "auto-rewind" for
>> AmAudioFile/IvrAudioFile? you remember VCR - some players had this
>> feature to automatically rewind the tape and eject it, if you had
>> watched it to the end. so you did not have to pay extra at the video
>> shop. just that here this would be a switch on the cassette
>> 'auto-rewind me if played to the end'.
>>
>> translated to code it might look like
>>
>> $ svn diff
>> Index: AmAudioFile.h
>> ===================================================================
>> --- AmAudioFile.h (revision 994)
>> +++ AmAudioFile.h (working copy)
>> @@ -106,6 +106,7 @@
>>
>> public:
>> AmSharedVar<bool> loop;
>> + AmSharedVar<bool> autorewind;
>>
>> AmAudioFile();
>> ~AmAudioFile();
>> Index: AmAudioFile.cpp
>> ===================================================================
>> --- AmAudioFile.cpp (revision 994)
>> +++ AmAudioFile.cpp (working copy)
>> @@ -213,7 +213,7 @@
>>
>> AmAudioFile::AmAudioFile()
>> : AmBufferedAudio(0, 0, 0), data_size(0),
>> - fp(0), begin(0), loop(false),
>> + fp(0), begin(0), loop(false), autorewind(false),
>> on_close_done(false),
>> close_on_exit(true)
>> {
>> @@ -322,6 +322,11 @@
>> rewind();
>> goto read_block;
>> }
>> +
>> + if (autorewind.get() && data_size>0){
>> + DBG("autorewinding audio file...\n");
>> + rewind();
>> + }
>>
>> ret = -2; // eof
>> }
>>
>> The ivr functions would be like the getters/setters 'loop' function
>> in IvrAudio.cpp. What do you think?
>>
>> Stefan
>>
>>
>> code fix:
>>
>> void AmPlaylist::updateCurrentItem()
>> {
>> if(!cur_item){
>> items_mut.lock();
>> if(!items.empty()){
>> if (items.front()){
>> DBG("making sure the file to be played is rewound\n");
>> AmAudioFile * p = (AmAudioFile*)items.front()->play;
>> p->rewind();
>> }
>> cur_item = items.front();
>> items.pop_front();
>> }
>> items_mut.unlock();
>> }
>> }
>>
>> Cheers
>> Jason Penton
>>
>>
>>
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Semsdev mailing list
>> [email protected] <mailto:[email protected]>
>> http://lists.iptel.org/mailman/listinfo/semsdev
>>
>>
>> -- Stefan Sayer
>> VoIP Services
>>
>> [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>
>> www.iptego.com <http://www.iptego.com>
>>
>> iptego GmbH
>> Am Borsigturm 40
>> 13507 Berlin
>> Germany
>>
>> Amtsgericht Charlottenburg, HRB 101010
>> Geschaeftsfuehrer: Alexander Hoffmann
>>
>>
>>
> --
> Stefan Sayer
> VoIP Services
>
> [EMAIL PROTECTED]
> www.iptego.com
>
> iptego GmbH
> Am Borsigturm 40
> 13507 Berlin
> Germany
>
> Amtsgericht Charlottenburg, HRB 101010
> Geschaeftsfuehrer: Alexander Hoffmann
>
Index: Ivr.cpp
===================================================================
--- Ivr.cpp (revision 830)
+++ Ivr.cpp (working copy)
@@ -41,7 +41,10 @@
#include <pthread.h>
#include <regex.h>
#include <dirent.h>
+#include <string>
+using std::string;
+
#include <set>
using std::set;
@@ -511,17 +514,27 @@
set<string> unique_entries;
regmatch_t pmatch[2];
- struct dirent* entry=0;
+ // Modified by Francois Hensley
+ // Because we are running on a 64 bit solaris
+ #if !defined(_LP64) && _FILE_OFFSET_BITS == 64
+ struct dirent64* entry;
+ #define readdir readdir64
+ #else
+ struct dirent* entry;
+ #endif
+
while((entry = readdir(dir)) != NULL){
-
+ printf("trying to load script with len name [%d] [%s]\n",entry->d_reclen, entry->d_name);
if(!regexec(®,entry->d_name,2,pmatch,0)){
string name(entry->d_name + pmatch[1].rm_so,
pmatch[1].rm_eo - pmatch[1].rm_so);
+ printf("Adding the script [%s]\n", entry->d_name);
unique_entries.insert(name);
}
}
+
closedir(dir);
regfree(®);
@@ -558,11 +571,15 @@
}
+int IvrDialog::refer(const string& target)
+{
+ return dlg.refer(target);
+}
+
int IvrDialog::transfer(const string& target)
{
return dlg.transfer(target);
}
-
int IvrDialog::drop()
{
int res = dlg.drop();
@@ -761,14 +778,14 @@
AmAudioEvent* audio_event = dynamic_cast<AmAudioEvent*>(event);
if(audio_event && audio_event->event_id == AmAudioEvent::noAudio){
-
+ DBG("IvrDialog::calling python event handler onEmptyQueue\n");
callPyEventHandler("onEmptyQueue", NULL);
event->processed = true;
}
AmPluginEvent* plugin_event = dynamic_cast<AmPluginEvent*>(event);
if(plugin_event && plugin_event->name == "timer_timeout") {
-
+ DBG("IvrDialog::calling python event handler onTimer\n");
callPyEventHandler("onTimer", "i", plugin_event->data.get(0).asInt());
event->processed = true;
}
Index: Ivr.h
===================================================================
--- Ivr.h (revision 830)
+++ Ivr.h (working copy)
@@ -138,6 +138,7 @@
void setPyPtrs(PyObject *mod, PyObject *dlg);
int transfer(const string& target);
+ int refer(const string& target);
int drop();
void onSessionStart(const AmSipRequest& req);
Index: IvrDialogBase.cpp
===================================================================
--- IvrDialogBase.cpp (revision 830)
+++ IvrDialogBase.cpp (working copy)
@@ -468,6 +468,25 @@
}
static PyObject*
+IvrDialogBase_refer(IvrDialogBase *self, PyObject* args)
+{
+ assert(self->p_dlg);
+
+ char* refer_to=0;
+ if(!PyArg_ParseTuple(args,"s",&refer_to))
+ return NULL;
+
+ if(self->p_dlg->refer(refer_to)){
+ ERROR("refer failed\n");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+static PyObject*
IvrDialogBase_redirect(IvrDialogBase *self, PyObject* args)
{
assert(self->p_dlg);
@@ -521,6 +540,9 @@
{"redirect", (PyCFunction)IvrDialogBase_redirect, METH_VARARGS,
"Refers the remote party to some third party."
},
+ {"refer", (PyCFunction)IvrDialogBase_refer, METH_VARARGS,
+ "Refers the remote party to some third party."
+ },
{"dropSession", (PyCFunction)IvrDialogBase_dropSession, METH_NOARGS,
"Drop the session and forget it without replying"
},
Index: Makefile.ivr_application
===================================================================
--- Makefile.ivr_application (revision 830)
+++ Makefile.ivr_application (working copy)
@@ -29,7 +29,7 @@
.PHONY: clean
clean:
- find . -iname "*\.pyc" -o -iname "*\.py~" | xargs rm -f
+ find . -name "*\.pyc" -o -name "*\.py~" | xargs rm -f
rm -f ${TARBALL_PREFIX}*.tar.gz
.PHONY: compile
@@ -38,10 +38,10 @@
.PHONY: install
install: all
- install -d ${BASEDIR}/${LIB_INSTALLDIR}
- install -m ${LIB_PERMISSIONS} *.pyc ${BASEDIR}/${LIB_INSTALLDIR}
- install -d ${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
- install -m ${LIB_PERMISSIONS} ${LIBDIR}/*.pyc ${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
+ ginstall -d ${BASEDIR}/${LIB_INSTALLDIR}
+ ginstall -m ${LIB_PERMISSIONS} *.pyc ${BASEDIR}/${LIB_INSTALLDIR}
+ ginstall -d ${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
+ ginstall -m ${LIB_PERMISSIONS} ${LIBDIR}/*.pyc ${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
.PHONY: install-cfg
install-cfg:
@@ -49,7 +49,7 @@
[EMAIL PROTECTED] r in $(module_conf_files); do \
echo installing $$r ; \
$(INSTALL-TOUCH) $(cfg-prefix)/$(cfg-dir)$$r ; \
- sed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \
+ gsed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \
-e "s#/usr/.*lib/sems/plug-in/#$(modules-target)#g" \
-e "s#/usr/.*etc/sems#$(cfg-target)#g" \
< $$r > $(cfg-prefix)/$(cfg-dir)$$r; \
@@ -60,7 +60,7 @@
@echo "please remove the files from ${LIB_INSTALLDIR} manually."
fulltest:
- find | grep /Test | grep -v ".svn" | grep \\.py$$ | sed -e "s#^./##g" | bash -e -
+ find | grep /Test | grep -v ".svn" | grep \\.py$$ | gsed -e "s#^./##g" | bash -e -
check:
find ${LIBDIR}/ | grep \\.py$$ | grep -v Test | PYTHONPATH=$(PYTHONPATH):$(IVRPATH)/moc xargs pychecker ${PYCHECKERARGS}
Index: IvrAudio.cpp
===================================================================
--- IvrAudio.cpp (revision 830)
+++ IvrAudio.cpp (working copy)
@@ -251,6 +251,37 @@
};
+static PyObject* IvrAudioFile_getautorewind(IvrAudioFile* self, void*)
+{
+ PyObject* autorewind = self->af->autorewind.get() ? Py_True : Py_False;
+ Py_INCREF(autorewind);
+ return autorewind;
+}
+
+static int IvrAudioFile_setautorewind(IvrAudioFile* self, PyObject* value, void*)
+{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
+ return -1;
+ }
+
+ if(value == Py_True)
+ self->af->autorewind.set(true);
+
+ else if(value == Py_False)
+ self->af->autorewind.set(false);
+
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "The first attribute value must be a boolean");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
static PyObject* IvrAudioFile_getloop(IvrAudioFile* self, void*)
{
PyObject* loop = self->af->loop.get() ? Py_True : Py_False;
@@ -281,6 +312,10 @@
}
static PyGetSetDef IvrAudioFile_getseters[] = {
+ {"autorewind",
+ (getter)IvrAudioFile_getautorewind, (setter)IvrAudioFile_setautorewind,
+ "must autorewind",
+ NULL},
{"loop",
(getter)IvrAudioFile_getloop, (setter)IvrAudioFile_setloop,
"repeat mode",
Index: Makefile
===================================================================
--- Makefile (revision 830)
+++ Makefile (working copy)
@@ -11,7 +11,7 @@
# put used Python modules from lib-dynload here, e.g. time, mysql, _cvs.so etc.
PYTHON_module_cflags = -I$(PYTHON_DIR) -fno-strict-aliasing
-PYTHON_module_ldflags = -Xlinker --export-dynamic \
+PYTHON_module_ldflags = -Xlinker \
-L$(PYTHON_LIBDIR)/config \
-lpython$(PY_VER)
@@ -29,7 +29,7 @@
LOCAL_INCLUDES = -I$(FLITE_DIR)/lang/usenglish
-module_ldflags = -lutil \
+module_ldflags = \
$(PYTHON_module_ldflags) \
$(IVR_TTS_module_ldflags)
Index: AmUtils.cpp
===================================================================
--- AmUtils.cpp (revision 830)
+++ AmUtils.cpp (working copy)
@@ -48,7 +48,6 @@
#include <sys/un.h>
#include <regex.h>
-
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 104
#endif
Index: AmPlaylist.cpp
===================================================================
--- AmPlaylist.cpp (revision 830)
+++ AmPlaylist.cpp (working copy)
@@ -25,6 +25,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "AmAudioFile.h"
#include "AmPlaylist.h"
#include "amci/codecs.h"
#include "log.h"
@@ -46,15 +47,16 @@
bool had_item = false;
if(cur_item){
- // if(cur_item->play)
- // cur_item->play->close();
+ /* if(cur_item->play)
+ cur_item->play->close();
- // if(cur_item->record)
- // cur_item->record->close();
-
- delete cur_item;
- cur_item = 0;
- had_item = true;
+ if(cur_item->record)
+ cur_item->record->close();
+ */
+ delete cur_item;
+ DBG("Deleteing cur_item\n");
+ cur_item = 0;
+ had_item = true;
}
updateCurrentItem();
@@ -71,11 +73,7 @@
cur_mut.lock();
updateCurrentItem();
- while(cur_item &&
- cur_item->play &&
- (ret = cur_item->play->get(user_ts,buffer,nb_samples)) <= 0){
-
- DBG("get: gotoNextItem\n");
+ while(cur_item && (ret = cur_item->play->get(user_ts,buffer,nb_samples)) <= 0){
gotoNextItem();
}
@@ -91,9 +89,12 @@
int AmPlaylist::put(unsigned int user_ts, unsigned char* buffer, unsigned int size)
{
int ret = -1;
-
cur_mut.lock();
updateCurrentItem();
+ //lets rewind the file quickly
+ //if (cur_item)
+ // cur_item->play->rewind();
+
while(cur_item &&
cur_item->record &&
(ret = cur_item->record->put(user_ts,buffer,size)) < 0){
Index: AmAudioFile.h
===================================================================
--- AmAudioFile.h (revision 830)
+++ AmAudioFile.h (working copy)
@@ -67,6 +67,7 @@
void setSubtypeId(int subtype_id);
};
+
/**
* \brief AmAudio implementation for file access
*/
@@ -106,6 +107,7 @@
public:
AmSharedVar<bool> loop;
+ AmSharedVar<bool> autorewind;
AmAudioFile();
~AmAudioFile();
@@ -125,9 +127,9 @@
* @return 0 if everything's OK
* @see OpenMode
*/
+
int open(const string& filename, OpenMode mode,
bool is_tmp=false);
-
int fpopen(const string& filename, OpenMode mode, FILE* n_fp);
/**
Index: AmAudioFile.cpp
===================================================================
--- AmAudioFile.cpp (revision 830)
+++ AmAudioFile.cpp (working copy)
@@ -24,13 +24,19 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#include "AmAudioFile.h"
#include "AmPlugIn.h"
#include "AmUtils.h"
#include <string.h>
+#include <stdio_ext.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+//namespace AmAudioFileFormata
+
AmAudioFileFormat::AmAudioFileFormat(const string& name, int subtype)
: name(name), subtype(subtype), p_subtype(0)
{
@@ -109,14 +115,17 @@
// return -1 if error
int AmAudioFile::open(const string& filename, OpenMode mode, bool is_tmp)
{
+ enable_extended_FILE_stdio(-1,-1);
close();
-
+ int n_fpi = 0;
this->close_on_exit = true;
FILE* n_fp = NULL;
if(!is_tmp){
n_fp = fopen(filename.c_str(),mode == AmAudioFile::Read ? "r" : "w+");
+ //using namespace std;
+ //n_fpi = open(filename.c_str(), O_RDONLY, 0644);
if(!n_fp){
if(mode == AmAudioFile::Read)
ERROR("file not found: %s\n",filename.c_str());
@@ -131,6 +140,7 @@
return -1;
}
}
+ //return n_fp;
return fpopen_int(filename, mode, n_fp);
}
@@ -211,7 +221,7 @@
AmAudioFile::AmAudioFile()
: AmBufferedAudio(0, 0, 0), data_size(0),
- fp(0), begin(0), loop(false),
+ fp(0), begin(0), loop(false), autorewind(false),
on_close_done(false),
close_on_exit(true)
{
@@ -320,6 +330,10 @@
rewind();
goto read_block;
}
+ if (autorewind.get() && data_size > 0){
+ DBG("autorewinding file");
+ rewind();
+ }
ret = -2; // eof
}
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev