By using the Aculab site, you agree with our use of cookies.
right  Talk To Us!

UAS API - Inbound With Speech Sample Application

  • Filename:

    samples/inbound_with_speech.py

    Description:

    An inbound application that prompts the caller to say a number between sixteen and ninety nine. After ringing and answering an inbound call, the application primes the speech recogniser to start recognising speech after the next play has ended. It selects a predefined grammar, SixteenToNinetyNine, for the recognition job. The application then uses TTS to ask for the caller's age, which should be between sixteen and ninety nine.

    The caller can respond by pressing digits instead of speaking. If this happens, the application will collect the DTMF digits that were pressed. Finally, the application will speak back to the caller what was said, or pressed, using TTS.

    Code:

    # -*- coding: utf-8 -*-
    """
    A simple application that answers an inbound call, speaks some TTS, 
    detects some speech and plays back the speech that was detected.
    
        Actions:
            - check the channel state
            - ring and answer
            - play some tts
            - detect a spoken response
            - play what was detected
            - hang up
    
    The speech detection grammar used is pre-defined.
    
    """
    
    from prosody.uas import Hangup, Error
    import time
    
    __uas_version__  = "0.0.1"
    __uas_identify__ = "application"
    
    def main(channel, application_instance_id, file_man, my_log, application_parameters):
        return_code = 0
        try:
            # check the incoming channel state
            state = channel.state()
    
            if state == channel.State.CALL_INCOMING:
                state = channel.ring()   # this can raise a Hangup exception
                if state == channel.State.RING_INCOMING:
                    state = channel.answer() # this can raise a Hangup exception
            else:
                raise Hangup('No inbound call, state is {0}'.format(state))
            if state != channel.State.ANSWERED:
                raise Hangup('Failed to answer inbound call, state is {0}'.format(state))
            
            my_log.info("Answered an inbound call") # log at info level
    
            channel.FileRecorder.start("speech_test_{0}.wav".format(application_instance_id))
            # prepare the speech detector, speech detection will begin as soon
            # as the prompt has finished playing
            my_grammar = channel.SpeechDetector.Grammar()
            my_grammar.create_from_predefined('SixteenToNinetyNine')
            if channel.SpeechDetector.prime(my_grammar, channel.SpeechDetector.SpeechDetectorTrigger.ONPLAYEND) is False:
                raise Error("Speech detector failed to start")
    
            # Say the TTS prompt, the text will ask the caller their age, a value from sixteen to ninety nine.
            cause = channel.FilePlayer.say("<acu-engine name='Polly'><voice name='Amy'>How old are you?</voice></acu-engine>")
            if cause != channel.FilePlayer.Cause.NORMAL:
                raise Error("Say prompt failed: cause is {0}".format(cause))
    
            # Now get the recognised speech, can be words or DTMF digits
            response = channel.SpeechDetector.get_recognised_speech()
            if channel.SpeechDetector.cause() == channel.SpeechDetector.Cause.BARGEIN:
                # age is 16 to 99, so we want two digits
                age = channel.DTMFDetector.get_digits(count=2)
            else:
                age = response.get_recognised_words_as_string()
            if not age:
                to_say = "Sorry, I did not hear that."
            else:
                to_say = "Your age is {0}.".format(age)
            # Say the recognised speech.
            cause = channel.FilePlayer.say("<acu-engine name='Polly'><voice name='Amy'>{0}</voice></acu-engine>".format(to_say))
    
            if cause != channel.FilePlayer.Cause.NORMAL:
                raise Error("TTS player returned {0}: expected {1}".format(cause, channel.FilePlayer.Cause.NORMAL))
            
            # Bye bye.
            cause = channel.FilePlayer.say("Bye bye.")
            if cause != channel.FilePlayer.Cause.NORMAL:
                raise Error("Say bye bye failed: cause is {0}".format(cause))
            
        except Hangup as exc:
            my_log.info("Hangup exception reports: {0}".format(exc))
             # in this app a hangup is not an error, return a positive value
            return_code = -100
            
        except Error as exc:
            # for error conditions return a negative value
            my_log.error("Error exception reports: {0}".format(exc))
            return_code = -101
            
        except Exception as exc:
            # an unexpected exception, return a negative value
            my_log.exception("Unexpected exception reports: {0}".format(exc))
            return_code = -102
            
        finally:
            channel.FileRecorder.stop()
            if channel.state() != channel.State.IDLE:
                channel.hang_up()
    
        return return_code