VoiceXML 2.1 Development GuideHome  |  Frameset Home

  Audio Tools and Links  |  TOC  |  G: Outbound Dialing  

Recording Audio

The ability to record audio from the phone is a pretty powerful function to have at our disposal, so let's look into some of the intricacies of what goes on behind the scenes, and learn how to properly manage our files.

There are three ways to record audio on the Prophecy VoiceXML platform. There is the <record> element, the <voxeo:recordcall> extension, and using the property value: <property name="recordutterance" value="true"/>.

<record> Element


The record element is designed for providing the best user experience during situations that require recording, and is generally best suited for those times when the user knows they are about to be recorded. The <record> element's attributes allow the user to know when the recording is to begin, and allows them to end the recording. Here's a simple script that takes a message and plays it back to the user:


<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

<form id="Main">

  <record name="rec" beep="true" dtmfterm="true" finalsilence="5s" maxtime="100s">
  <!--Explanation:
      name="rec"          Our variable to reference for playback
      beep="true"        Talk after the beep.
      dtmfterm="true"    Pressing any DTMF ends recording
      finalsilence="5s"  They may forget to press that ending DTMF
      maxtime="100s"      You want a full hard drive of stories about Aunt Ruth?
  -->
 
    <prompt>
      I'm busy right now, honey. How's your Aunt Ruth?
    </prompt>

    <filled>
      <log expr="rec$.duration"/>
      <log expr="rec$.termchar"/>
      <log expr="rec$.size"/>

      <!-- We all love to hear our own voices: -->
      <prompt> your recording was <value expr="rec"/> </prompt>
     
      <submit expr=example.php method="post" namelist="rec" enctype="multipart/form-data"/>
    </filled>

  </record>
</form>
</vxml>


recordutterance Property


The recordutterance is a handy way to manage recording according to scope irregardless of grammar matches. You may remember the shadow variable application.lastresult$.utterance will give us the last recognized grammar match. The recordutterance property gives us the entire utterance and places it into the variable application.lastresult$.recording.  This is a great debugging tool that allows you to debug grammars, or keep recordings of calls that go wrong. Here's an example that sends us a recording when we fail to get a grammar match:


<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1">

  <form>
    <property name="recordutterance" value="true"/>
    <property name="incompletetimeout" value="4s"/>

    <field name="flavors">
    <prompt>
      What is your favorite flavor of ice cream?
    </prompt>

    <grammar type="application/srgs+xml" src="flavor.grxml"/>

    <nomatch>
        <var name="rec" expr="application.lastresult$.recording"/>
        <prompt>I have never heard of <value expr="rec"/> ice cream! I will make a note to try that.</prompt>
       
        <log expr="application.lastresult$.duration"/>
        <log expr="application.lastresult$.size"/>
        <submit method="post" enctype="multipart/form-data" next="example.php" namelist="rec"/>
    </nomatch>
    </field> 
  </form>
</vxml>


<voxeo:recordcall> Element


The <voxeo:recordcall> extension has the benefit of recording both sides of a call. The recording will outlive the call as the WAV file is saved for future retrieval. On Evolution the file is saved in your recordings directory under a directory structure based on the date, ie. root/recordings/year/month/day/. One easy way to get those files by the batch is to use FTP access like so: ftp://[voxeo-username]:[voxeo-password]@ftp.voxeo.net. If you are using a locally installed version of Prophecy then your files will be saved to:
Voxeo\www\MRCP\Recordings. The "info" attribute inserts text into the file's name. This makes searching and sorting your wav files much easier.

The powerful "value" attribute of <voxeo:recordcall> allows you to turn recording on or off, or to determine a percentage of calls that are recorded. Here's an example that records some, all or none of the calls based on who is calling:


<?xml version="1.0" encoding="UTF-8" ?>

<!-- declaring the 'xmlns:voxeo' attribute is required -->

<vxml version="2.1" xmlns="http://www.w3.org/2001/vxml"
    xmlns:voxeo="http://community.voxeo.com/xmlns/vxml">

    <form id="Main">
   
        <field name="caller" type="digits?length=1">
            <prompt>
                Employees please press 1.<break/>
                Managers please press 2.<break/>
            </prompt>
          <grammar xml:lang="en-US" root = "TOP" mode="dtmf">
            <rule id="TOP" scope="public">
              <one-of>
                  <item> 1 <tag> <![CDATA[  <caller "employee"> ]]>  </tag> </item>
                  <item> 2 <tag> <![CDATA[  <caller "manager"> ]]>  </tag> </item>
              </one-of>
            </rule>
          </grammar>

            <filled>
                  <if cond="caller=='employee'">
                      <!-- Record 10% of employee calls. -->
                      <voxeo:recordcall value="10" info="employee" />
                     
                  <elseif cond="caller=='manager'"/>
                      <!-- Record 100% of manager calls. -->
                      <voxeo:recordcall value="100" info="manager" />
                     
                  <else/>
                      <!-- We don't know who this is so record no calls. -->
                      <voxeo:recordcall value="0" info="unknown" />
                  </if>
                  <goto nextitem="restOfCall"/>
            </filled>
        </field>

        <block name="restOfCall">
            <prompt>
                Please hold while we transfer you.
                <!-- and so forth and so on... -->
            </prompt>
            <exit/>
        </block>
    </form>
</vxml>


When we record an audio file on the Voxeo network using either <record> or recordutterance, we will store the file in a local temp directory, which will allow you to playback the message while still within the app. However, if you want to keep this recorded file for future use, you will have to move it somewhere before we exit from the application. The good news is, Voxeo has provided a number of sample scripts below in a variety of server-side flavors to let you in on the necessary syntax.

Keep in mind if you are using ASP as a backend, when you submit recorded audio specifying 'multipart/form-data', all of the fields passed, even the text ones, are all contained in the binary data sent and it is up to the script page to parse it out correctly. Using a 'Request.Form' will cause an error because the text data can't be sent separately.



ASP Example

Record_One.xml

The following code prompts for a recording and submits the recorded audio along with a query string varialbe to to 'RecordMessage.asp'.


<?xml version='1.0'?>
<vxml version="2.0">

  <form id="main">
    <record name="CallersMessage" beep="true" maxtime="60s" finalsilence="2500ms" type="audio/wav">
      <prompt>
        Please record your message after the beep. You may record a message up to sixty seconds long. To end recording,
        press  any key or simply quit speaking.
      </prompt>
    </record>

    <field name="confirmMessage" type="boolean">
      <prompt>
        I heard you say <value expr="CallersMessage"/>. To save this message say yes. To discard it say no.
      </prompt>
 
      <filled>
        <if cond="confirmMessage">
          <goto nextitem="askName"/>
        <else/>
          <goto next="#main"/>
        </if>
      </filled>

    </field>

    <field name="askName">
      <prompt>
        are you Jim, Jackson, or Aaron?
      </prompt>

      <grammar type="text/gsl"> [ aaron jackson jim ] </grammar>

      <filled>
        <if cond="askName == 'jim' || askName == 'jackson' || askName == 'aaron'">
            <submit expr="'RecordMessage.asp?askName='+askName"
              method="post" namelist="CallersMessage" enctype="multipart/form-data"/>
        <else/>
          <prompt>
            sorry charlie, we will not submit your file.
          </prompt>
        </if>
      </filled>
    </field>
  </form>
</vxml>


'RecordMessage.asp

The following code saves the recorded file (with the help of upload.inc) and speaks the name sent in the query string.


<!--#include file="upload.inc"-->
<%
byteCount = Request.TotalBytes
RequestBin = Request.BinaryRead(byteCount)
Dim UploadRequest
Set UploadRequest = CreateObject("Scripting.Dictionary")

BuildUploadRequest  RequestBin
picture = UploadRequest.Item("CallersMessage").Item("Value")
Filename = DatePart ( "h" , Now ) & DatePart ( "m" , Now ) & DatePart ( "s" , Now ) & DatePart ( "m" , Now ) & DatePart ( "d" , Now ) & DatePart ( "yyyy" , Now ) & ".wav"
Set FileSystem = CreateObject ("Scripting.FileSystemObject" )
Set WaveFile = FileSystem.CreateTextFile ( Server.MapPath ( filename ) )
WaveFile.Write getString(picture)
WaveFile.Close
Set WaveFile = Nothing
Set FileSystem = Nothing

%><?xml version='1.0'?>
<vxml version="2.0">

  <form>
    <block>
      <prompt>
        Thanks, <% =Request.Querystring("askName")%> Your message has been saved.
      </prompt>
    </block>
  </form>
</vxml>


upload.inc

This file processes the posted content, separating the file from the query string parts.


<%
Dim Filename
Dim FileSystem
Dim WaveFile
Dim binRead
Dim byteCount

'Byte string to string conversion
Function getString(StringBin)
getString =""
For intCount = 1 to LenB(StringBin)
    getString = getString & chr(AscB(MidB(StringBin,intCount,1)))
Next
End Function

'String to byte string conversion
Function getByteString(StringStr)
For i = 1 to Len(StringStr)
char = Mid(StringStr,i,1)
getByteString = getByteString & chrB(AscB(char))
Next
End Function 

Sub BuildUploadRequest(RequestBin)

    'Get the boundary
    PosBeg = 1
    PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13)))
    boundary = MidB(RequestBin,PosBeg,PosEnd-PosBeg)
    boundaryPos = InstrB(1,RequestBin,boundary)


    'Get all data inside the boundaries
Do until (boundaryPos=InstrB(RequestBin,boundary & getByteString("--")))

        'Members variable of objects are put in a dictionary object
        Dim UploadControl
        Set UploadControl = CreateObject("Scripting.Dictionary")


        'Get an object name
        Pos = InstrB(BoundaryPos,RequestBin,_
                    getByteString("Content-Disposition"))
        Pos = InstrB(Pos,RequestBin,getByteString("name="))
        PosBeg = Pos+6
        PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(34)))
        Name = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
PosFile=InstrB(BoundaryPos,RequestBin,getByteString("filename="))
        PosBound = InstrB(PosEnd,RequestBin,boundary)
        'Test if object is of file type
        If  PosFile<>0 AND (PosFile<PosBound) Then
        'Get Filename, content-type and content of file
        PosBeg = PosFile + 10
        PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(34)))
        FileName = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
        'Add filename to dictionary object
        UploadControl.Add "FileName", FileName
        Pos = InstrB(PosEnd,RequestBin,getByteString("Content-Type:"))
        PosBeg = Pos+14
        PosEnd = InstrB(PosBeg,RequestBin,getByteString(chr(13)))
        'Add content-type to dictionary object
        ContentType = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
        UploadControl.Add "ContentType",ContentType
        'Get content of object
        PosBeg = PosEnd+4
        PosEnd = InstrB(PosBeg,RequestBin,boundary)-2
        Value = MidB(RequestBin,PosBeg,PosEnd-PosBeg)
    Else
        'Get content of object
        Pos = InstrB(Pos,RequestBin,getByteString(chr(13)))
        PosBeg = Pos+4
        PosEnd = InstrB(PosBeg,RequestBin,boundary)-2
        Value = getString(MidB(RequestBin,PosBeg,PosEnd-PosBeg))
    End If

        'Add content to dictionary object
        UploadControl.Add "Value" , Value   
'Add dictionary object to main dictionary
UploadRequest.Add name, UploadControl   
        'Loop to next object
        BoundaryPos=InstrB(BoundaryPos+LenB(boundary),RequestBin,boundary)
Loop
End Sub
%>



Cold Fusion Example 1

RecUpload.cfm

The following code handles both the recording and saving of an audio file.


<?xml version='1.0'?>
<vxml version="2.0">

<cfheader name="Cache-Control" value= "no-cache">
<cfheader name="Expires" value="#Now()#">

<CFIF IsDefined("form.greeting")>
<CFFILE Action="upload"
filefield="form.greeting"
destination="#getdirectoryfrompath(getcurrenttemplatepath())#"
mode="777"
nameconflict="makeunique">
  <form>
    <block>
      <prompt>
        We have saved this audio file to the server.
          <audio src="<CFOUTPUT>#serverfile#</CFOUTPUT>" />
        Please call back to record again.
      </prompt>
    </block>
</form>

<CFELSE>
<form>
  <record name="greeting" beep="true" maxtime="30s" finalsilence="4000ms" type="audio/wav">
    <prompt>
      At the tone, please say your greeting.
    </prompt>

    <noinput>
      I didn't hear anything, please try again.
    </noinput>

    <nomatch>
      Your greeting is <value expr="greeting"/>.
    </nomatch>
  </record>

  <field name="confirm" type="boolean">
    <prompt>
      Your greeting is <value expr="greeting"/>.
      To keep it, say yes. To discard it, say no.
    </prompt>

    <filled>
      <if cond="confirm">
        <submit next="RecUpload.cfm" method="post" namelist="greeting" enctype="multipart/form-data"/>
    </if>

    <clear/>
    </filled>
  </field>
</form>

</CFIF>
</vxml>



Cold Fusion Example 2

CF_Mailto.cfm

The following code handles both the recording and emailing of an audio file.


<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0">


<CFIF IsDefined("form.greeting")>
<CFFILE Action="upload"
filefield="form.greeting"
destination="#getdirectoryfrompath(getcurrenttemplatepath())#"
mode="777"
nameconflict="makeunique">

<CFMAIL TO="me@here.com"
                                FROM="you@there.com"
                            SUBJECT="WAV EMAIL TEST">
            Attached is your saved wav file.
      <CFMAILPARAM
              FILE="#file.serverdirectory#\#file.serverfile#">
</CFMAIL>

<form>
  <block>
    <prompt>
      Data recieved.Thanks for recording.
    </prompt>
  </block>
</form>

<CFELSE>
<form>
  <record name="greeting" beep="true" maxtime="10s" finalsilence="4000ms" type="audio/wav">
    <prompt>
      At the tone, please say your greeting.
    </prompt>

  <noinput>
      I didn't hear anything, please try again.
    </noinput>
  </record>

  <field name="confirm" type="boolean">
    <prompt>
      Your greeting is <value expr="greeting"/>.
      Our shadow var for duration is <value expr="greeting$.duration"/>,
      for size is <value expr="greeting$.size"/>
      and for term character is <value expr="greeting$.termchar"/>
    </prompt>

    <prompt> 
      To keep this message, say yes. To discard it, say no.
    </prompt>

    <filled>
      <if cond="confirm">
        <submit next="cfrecord.cfm" method="post" namelist="greeting" enctype="multipart/form-data"/>
    </if>
    <clear/>

    </filled>
  </field>
</form>

</CFIF>
</vxml>



JSP Example

record_prompt.xml

The following code submits a recording and some variables to 'record_save.jsp'.

<?xml version='1.0'?>
<vxml version="2.0">
    <form>
        <record name="audio" maxtime="120s" finalsilence="4s" beep="true" dtmfterm="true">
            <prompt bargein="false">
                Start recording after the beep.  Press any dtmf key when finished.
            </prompt>

            <filled>
                <assign name="firstname" expr="'professor'" />
                <assign name="lastname" expr="'falken'" />
                <submit next="record_save.jsp"
                        namelist="firstname lastname audio"
                        enctype="multipart/form-data"
                        method="post" />
            </filled>
        </record>
    </form>
</vxml>


record_save.jsp

The following code saves the audio and outputs the posted variables.

<%
/*
Download the oreilly servlet classes from http://www.servlets.com/cos/index.html

The download will include several classes, however we're only going to be using
the MultipartRequest class for this example.  For more flexibility/customization,
you may need to use the MultipartParser class.  The oreilly download includes
sample code for both classes.
*/

boolean SUCCESS = true; //always optimistic...
String firstname = ""; //default
String lastname = ""; //default

try {
    //set the destination for the recorded audio file
    String dir = application.getRealPath("/audio"); //modify as necessary

    //process the request object, save the audio part, parse the posted variables
    com.oreilly.servlet.MultipartRequest mr = new com.oreilly.servlet.MultipartRequest(request, dir);
   
    //assign our posted variables
    firstname = mr.getParameter("firstname");
    lastname = mr.getParameter("lastname");
} catch (Exception e) {
    SUCCESS = false;  //something went wrong.
}

//we've finished the record attempt.  Output vxml with the status...
%>
<?xml version='1.0'?>
<vxml version="2.0">
<form>
    <block>
      Greetings,
<%
        out.print(firstname + " " + lastname + ".");

        if (SUCCESS)
            out.print(" The save succeeded.  Now, how about a nice game of chess.");
        else
            out.print(" Unfortunately, the save failed.");
%>
    </block>
</form>
</vxml>


PHP Example

Record_Upload_HTTP_POST.php

The following catcher script illustrates how one might handle the saving of a posted file in PHP.

Note: This code is designed for php version 4.0.1, newer versions will require modification

<?PHP
header('Cache-Control: no-cache');

error_reporting (0);

echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
echo "<vxml version=\"2.0\">";

echo "<form id=\"main\">";
echo "<block>";

if ($HTTP_POST_FILES) {
  foreach ($HTTP_POST_FILES as $key => $value) {
    foreach ($value as $Filename) {

      if (strpos($Filename, "WINNT")) { $ServerSide = $Filename; }
      if (strpos($Filename, ".wav"))  { $ClientSide = $Filename; }
    }  // for each statement

    $ServerSide = str_replace("\\\\", "/", $ServerSide);

    if (!copy($ServerSide, "c:/audio-storage/temp.wav")) {
      echo "Could not save filename: " . $ServerSide;
    } // if statement
    else {
      echo "Successfully saved filename: " . $ServerSide;
    }  // else statement

  }  // for each statement
}  // if statement

echo "</block>";
echo "</form>";
echo "</vxml>";
?>



  ANNOTATIONS: EXISTING POSTS
riyer
11/21/2005 5:34 PM (EST)
To record & store audio data, do I need to upgrade to professional evolution on voxeo?
MattHenry
11/21/2005 5:38 PM (EST)


Hello Riyer,

I'm going to take a guess on where it is that you are coming from on this inquiry. Can I assume that you are asking about the ability to use a JSP/PHP/etc script hosted on the voxeo servers that will store audio data for you?

Note that if you have a host that is JSP/ASP/etc-capable, then you should be able to run the code sample of your choice and store recorded audio without any cost at all.

~Matt

riyer
11/21/2005 5:55 PM (EST)
Thanks Matt. My host sits behind a firewall. I will dig around a little more to see how I can set this up --
symphonyx
5/10/2006 9:55 AM (EDT)
Thanks Matt.

Greetings from Chile.

Bye,
symphonyx
5/10/2006 2:41 PM (EDT)
Here the problem solved using vxml+php.

When submit a record the post to php is :

file://localhost/yourtempwavfolder/yourtempfile.wav

Is necessary "cut" the "file://localhost/" to get the correct file path.

record.vxml
<?xml version="1.0"?>
<vxml version="2.0">
    <form>
        <record beep="true" name="file" type="audio/x-wav" maxtime="5s"
        dtmfterm="true">
            <prompt>
              Say something. Press any key to stop recording.
            </prompt>
            <noinput>
              I can't heard you.
            </noinput>
            <filled>
                <prompt>
                    Your message <value expr="file" />
                </prompt>
<submit next="php/upload.php" method="post" namelist="file" enctype="multipart/form-data" />
          </filled>
      </record>
  </form>
</vxml>   

upload.php
<?
header('Cache-Control: no-cache');

include 'util.php';

$MAX_FILE_SIZE = 15000000;

$folder = "/tmp/";
$logfile = "log.txt";

// Post variables
$fname = $HTTP_POST_FILES['file']['name'];
$ftype = $HTTP_POST_FILES['file']['type'];
$fsize = $HTTP_POST_FILES['file']['size'];
$ftmp = $HTTP_POST_FILES['file']['tmp_name'];

//save log
$handler=fopen($folder.$logfile,"w");
fwrite($handler,the_file_name($fname));
fclose($handler);

if($fize > $MAX_FILE_SIZE){$error = 2;}

if(file_exists($folder."m_".$fname)){$error = 3;}

if(copy(the_file_name($fname),$ftmp."wav")) {$error = 0;}

switch($error){
case'0':
$mensaje="File saved Ok.";
break;
case'1':
$mensaje="Incorrect Format.";
break;
case'2':
$mensaje="File so Big.";
break;
case'3':
$mensaje="File already exists.";
break;
}

echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
echo "<vxml version=\"2.0\">";
echo "<form id=\"main\">";
echo "<block>";
echo $mensaje;
echo "</block>";
echo "</form>";
echo "</vxml>";
?>

util.php
<?php

function the_file_name($file){
    $j=0;
    $l=strlen($file);
    for ($k=0;$k<=$l;$k++){
if (substr($file,$k,1)=='/'){
  $j++;
  if ($j==3){
    return substr($file,$k);
  }
}
    }
   
    return "";
}   
?>

Greetings from Chile.

Luis
fayyazkl
2/15/2007 2:50 AM (EST)
Hi,

Can i record audio along with simultaneously playing a song to caller. If this is possible, please provide some directions to do so.

Thanks,

Fayyaz
mikethompson
2/15/2007 9:27 AM (EST)
Hi Fayyaz,

Unfortunately, this is not natively supported within VoiceXML.  However, if you *really* want to achieve this functionality, you will want to use CallXML or CCXML.  This way, you can create a conference and join in another CallXML leg which simply records.  Then dial another seperate CallXML application (and join it into the conference) to do the audio streaming.  I know it is a lot of work for something which sounds simple, but this is currently the best way to approach recording audio while streaming audio.  If you want to get started with this, here are some helpful links:

http://docs.voxeo.com/callxml/2.0/t_14cxml.htm?search=conference#anchor
http://docs.voxeo.com/callxml/2.0/joinconference.htm?search=conference#anchor

Best,
Mike Thompson
Voxeo Corporation

danielvinson
2/18/2007 1:13 PM (EST)
Hiya

The ASP example seems to work when hosted on the Voxeo server.  However I assume the Cold Fusion, JSP and PHP examples require specific servers.  Is this correct?  Can you tell me the advantage of using CF, JSP or PHP over ASP?

The CF 2 example allows the caller to send the recorded message.  Is it possible to do this in XML or ASP?

Thanks

Daniel
VoxeoTony
2/18/2007 5:21 PM (EST)
Hi Daniel,

Your questions are covered in the posting at http://docs.voxeo.com/voicexml/2.0/intro_serverside.htm?search=server#anchor

However, since ASP is native to the Windows server environment the ASP example would be able to work on the hosted platform.

We hope this helps you along.

Tony~
danielvinson
2/19/2007 5:27 PM (EST)
Hi Tony

Thanks for the link.  Understand a bit better now.

But using the ASP code when hosted on the Voxeo server...is this dynamic?

Sorry for repeating myself but is it possible to write the ASP code such that it will email the recorded message or is this only available in CF, JSP etc

Thanks

Daniel
VoxeoTony
2/19/2007 6:12 PM (EST)
Hello Daniel,

I'm glad you were able to get some insight to your questions.  For your questions on ASP we do know that ASP as a language is very powerful.  The example on the site is dynamic in the sense that it is not a static file being sent off to the application.

I do know that ASP will be able to email when properly coded.  While we do not have examples for this in the tutorial, doing a search for ASP email examples should prove useful.

Please let us know if this information helps.

Regards,


Tony


fayyazkl
2/20/2007 3:04 AM (EST)

Hi Mike and others!

Thank you very much for such a prompt response and favor. I just needed some further info. If i use a conference call for achieving simultaneous playback and recording, is it possible that i be charged a single call?

Actually, i am working on an application which once go into production will obviously be charged per call through your network. However, we don't want to double that cost by making two calls per customer. Could you suggest a way out or something??

Thanking in anticipation.

Fayyaz Khan Lodhi
MattHenry
2/20/2007 2:41 PM (EST)


Fayyaz,

This is really dependent on the nature of the application you are running, the amount of traffic that you are willing to commit to, and several other factors. As this is really a question of pricing, I think it might be best to direct such inquiries to sales@voxeo.com. As each customer has their own specific needs, each customer contract is going to be a little bit different in terms of what is billed.

Hope this helps,

~Matthew henry
fayyazkl
3/7/2007 2:51 AM (EST)
Hi Mike and others,

Further to my question above i.e. i want to play a song to the caller while recording his voice simultaneously, I have learned conferencing with CCXML. But problem i am facing is, Conference is created when we call separate numbers, they are picked up by different people and we join these legs.

But here i have a single caller who calls my application, the application picks up, and records his voice. If i want to play him a song while doing this, how would i call him in the middle of his running call?

May be i have missed a point or have not explained my needs to you clearly. Please advise.

Fayyaz Khan Lodhi
MattHenry
3/7/2007 4:07 PM (EST)


To be clear:

You have an app outdial app that, upon pickup by only a single party, will play a .wav file, and record the caller input, is this correct? If this is the case, then I would think that using a code structure with block/audio would serve to address the first part of the equation, and the <voxeo:recordcall> element would allow you to record both sides of the call.

Is this what you are looking for? The finer details aren't very clear to me, so please forgive me if this is off-topic.

~Matt
fayyazkl
3/8/2007 1:57 AM (EST)

Dear Matt,

You almost understood correctly but missed one part i guess so i will elborate once to be clear.


A user calls my in bound application i.e. he has the number attached to my application and he makes a call through normal phone. Upon picking the call, the application starts playing a song to him. During this play back he starts singing as well. And i want to record ONLY HIS SINGING and not the song played by application. Moreover, these two things i need to take place at the same time.

From what you suggested, if i play with block/audio and then use voxeo :recordcall, recording will start AFTER the song being played is completed i.e. the playing and recording wont occur in parallel. Whereas my needs are to get both the functionalities done in parallel.

Hope i have clarified my query. Hoping for a solution.Thanks

Fayyaz
MattHenry
3/8/2007 3:10 PM (EST)


Hello Fayyaz,

This might be a bit tricky. There aren't any provisions within the VXML specification for simultaneous recording and input, where we can block out one of the audio streams, (a half-duplex connection). You *might* be able to figure a way to do this via a CCXML wrapper that <joins> two seperate legs, (one full duplex, the other half-duplex), but then we have the problem of how to disambiguate the prerecorded audio, and the callers voice input into the recorded file that you wish to generate.

Much as I hate to say it, I'm not seeing a really easy way around this, as this is somewhat outside the boundaries of what VoiceXML is really designed to do.

Regards,

~Matthew henry

kubeworks
3/22/2007 12:55 AM (EDT)
when i try the CF2 example i get an error.  I tried changing the cfrecord.cfm to the same name as my file and it gives me server as internal error.

Is there really a seperate CF script to be able to successfully do this test on CF?
jbassett
3/22/2007 6:44 AM (EDT)
Hello,

The tutorial is for the recording and email of a file and should work by itself. If you feel there is something wrong, feel free to log in to your account and open a support forum ticket and wwe will be glad to assist you.

You can also use the "Support" tab in the Debugger window to email us the logs from a failed session.  This will give us a much better base of information to troubleshoot with, ultimately shortening the time to resolution.

Thanks
Jesse Bassett
Voxeo Support
georgelai
8/26/2007 6:26 AM (EDT)
I have tried and tried the php post script, and your php example fails every time, with the message: Could not save filename: file-1188123569661.wav

I even tried to change the { $ClientSide = $Filename; } to { $ServerSide = $Filename; } because the code was recognizing only ".wav" but it still failed to save.

What is going on? From putting in the php code:

echo "<log expr=\"'".$Filename."'\" />";

I see the following:

LOG: file-1188123569661.wav
LOG: audio/x-wav
LOG: /tmp/phplVRimF
LOG: 0
LOG: 27134

Help, please!  This is driving me crazy!
MattHenry
8/27/2007 3:31 PM (EDT)


George,

To be clear, *which* PHP code are you using? Is it the PHP in our tutorial, or the code posted by username "symphonyx" on 5/10/2006 2:41 PM (EDT)? Note that we aren't habit of providing dynamic coding support, but if you can provide us with some indication as to what is failing, and how, perhaps I can lend a hand.


~Matt
rastgoo
5/16/2008 1:34 PM (EDT)
Hi
I was looking at  w3
And here is what I have saw in definition of record tag

"Platform support for recognition of speech grammars during recording is optional."

Essentially this is exactly what we need to do.
according to specification if input phrase match local grammer we should be able to get the interpretation thourgh application.lastapplication.lastresult$

Her is the link to specification
http://www.w3.org/TR/voicexml20/#dml2.3.6

Also some platform supports the same functionality through <field> tag and using shadow vaiables.

Also consider that <record> tag can have a child tag of <grammar> so look like there has to be some recognition functionality available via record rag.

Sincerely
rastgoo
5/16/2008 1:36 PM (EDT)
I forgot to mentioned that all of my test have failed till now.
here is the sample code which I tried to use

<?xml version="1.0"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml">
    <form>
        <script>
            <![CDATA[
    function dumpResults(){
        var result = "something";
        for ( var i = 0; i < application.lastresult$.length; i++ ){
            result += "Utterance  is "+application.lastresult$.utterance + ".";
            result += "Utterance  is "+application.lastresult$.interpretation+ ".";
        }
        return result;
    }
    function dumpResults2(){
        var result = application.lastresult$.length;
        return result;
    }
    ]]>
        </script>
        <record name = "digit">
        <!--record name="digit"-->
            <grammar src="builtin:grammar/digits"/>
           
            <prompt bargein="true">
                <audio src="/vxml/audio/FD4945.VOX" fetchhint="prefetch"/>
            </prompt>
            <noinput>
                <audio src="/vxml/audio/FD4943.VOX" fetchhint="prefetch"/>
            </noinput>
            <nomatch>
                <audio src="/vxml/audio/FD4945.VOX" fetchhint="prefetch"/>
            </nomatch>
            <filled>
<log >++++++++++++++++++++++<value expr = "dumpResults()" /></log>
<audio src="/vxml/audio/FD4941.VOX" fetchhint="prefetch"/>

            </filled>
        </record>
<!--/record-->
    </form>
</vxml>

I appriciate any help on this regard.
VoxeoDustin
5/27/2008 2:58 PM (EDT)
Hey Rastgoo,

You are correct. I have reproduced this behavior and it does not agree with the spec. I have opened an internal Engineering ticket to address this issue and it will be resolved in a future build of Prophecy.

Cheers,
Dustin
fahdbaig
6/25/2008 6:11 AM (EDT)
Hi,

I was wondering if its possible to record the speech in say 2 seconds chunks as the caller speaks? In other words, as the speaker is speaking every 2 seconds his/her speech is recorded as a WAV file. I'll have another application that will be taking in these WAV files, as they are recorded, and process them.
Can you guide me on how to do this.

Thank you very much.
Fahd
VoxeoDustin
6/25/2008 9:30 AM (EDT)
Hey Fahd,

Unfortunately, the VoiceXML spec does not provision for the ability to split the audio files into 2 second pieces. This is something that would need to be handled with post processing on the server side.

Let me know if we can be of further assistance.

Thanks,
Dustin
bilal
7/7/2008 11:09 AM (EDT)
hi there,
I tried the .asp script and recorded the file. But i am not able to open the wave file generated as a result. It seems to be corrupt or not properly written. I wanted to know if it was only me or somebody else also has had this problem. Thanks.
MattHenry
7/7/2008 1:41 PM (EDT)


Hi there,

This could be due to a poor FTP connection, or any other number of issues on the server-side. You might try specifying an FTP destination for webhosting on our servers to see if it makes a difference:

ftp://[USERNAME]:[PASSWORD]@ftp-internal.voxeo.net

Hope this helps,

~Matthew Henry
dmchugh
7/17/2008 2:13 PM (EDT)
Does the 'submit' tag support Https?

<submit expr="'https://myserver.com/RecordMessage.asp?askName='+askName"
              method="post" namelist="CallersMessage" enctype="multipart/form-data"/>

VoxeoBrian
7/17/2008 2:56 PM (EDT)
Hello,

Indeed, HTTPS/SSL is fully supported on the Voxeo Network provided the webserver is utilizing a cert found in our stock java keystore.

For your reference, and if you are searching for a certificate vendor I am attaching our keystore to this ticket.

Let me know if this helps.

Thanks,

Brian
Magician
10/14/2008 6:05 AM (EDT)
Greetings & Salutations,

Much thanks for your help on this problem, as well as all the others submitted by myself and my voice magic friends.

Within the ASP example, you have an ending piece of VXML code which I would like to eliminate. I have tried just losing the <prompt> and its contents. This seems to disconnect my call.

When I try to eliminate the VXML entirely from within the ASP, it fails.

Ideally, I would like to eliminate the piece after the <% %> header block and run the RecordMessage.asp blind. I believe that this piece is teminating my call.

Your magic spells to cure this problem would be sincerely appreciated.

Magician

voxeoJeffK
10/14/2008 7:49 AM (EDT)
Hi,

The call will terminate if there is no VXML left to execute, so the ASP document outputs VXML back to the voice browser. Since the original VXML page uses <submit> to send the recording to the ASP page, that VXML document is done and gone. We need to have a new VXML document output back to the browser to continue with the call.

Regards,
Jeff K.

login
  Audio Tools and Links  |  TOC  |  G: Outbound Dialing  

© 2008 Voxeo Corporation  |  Voxeo IVR  |  VoiceXML & CCXML IVR Developer Site