0

I am trying to take a streamed audio and convert it to text using Google text to speech. Then pass that that text as input to a conversation not on Watson. Watson then returns its answer. The latter half works great.

The issue I am having is that I can't get the script to pass the text from the recorded speech to the Watson service I created.

I don't get an error, I just get nothing. The mic is working (I tested it with another script). The program actually indicates I could understand my response (no text I assume). Here is my code

import os
import watson_developer_cloud

import speech_recognition as sr
from gtts import gTTS
import watson_developer_cloud
import time

# Set up Assistant service.
service = watson_developer_cloud.AssistantV1(
  #username = 'USERNAME', # replace with service username
  #password = 'PASSWORD', # replace with service password

  iam_api_key = 'xxxxxxxxxx', # replace with service username
  url = 'xxxxxxxxxx', # replace with service password
  version = 'xxxxxxxxxx'
)
workspace_id = 'xxxxxxxxxxxxxx' # replace with workspace ID

def getaudiodevices():
    devices = os.popen("arecord -l")
    device_string = devices.read()
    device_string = device_string.split("\n")
    for line in device_string:
        if line.find("card") != -1:
            print("hw:" + line[line.find("card") + 5] + "," + line[line.find("device") + 7])

def speak(audiostring):
    print(audiostring)
    tts = gTTS(text=audiostring, lang='en')
    tts.save('audio.mp3')
    os.system('mpg321 audio.mp3')

def recordaudio():
    # Record Audio
    r = sr.Recognizer()
    with sr.Microphone(0) as source:
        print("Say something!")
        audio = r.listen(source,phrase_time_limit=10)
    # Speech recognition ******
    data = " "
    try:
        data = r.recognize_google(audio)
        print("You said: " + data)
    except sr.UnknownValueError:
        print("Google Speech Recognition could not understand audio")
    except sr.RequestError as e:
        print("Could not request results from Google Speech Recognition service; {0}".format(e))

    return data

# Initialize with empty value to start the conversation.
user_input = ''
context = {}
current_action = ''

# Main input/output loop
while current_action != 'end_conversation':

  # Send message to Assistant service.
  response = service.message(
    workspace_id = workspace_id,
    input = {
      'text': user_input
    },
    context = context
  )

  # Print the output from dialog, if any.
  if response['output']['text']:
    print(response['output']['text'][0])
    speak(response['output']['text'][0])

  # Update the stored context with the latest received from the dialog.
  context = response['context']
  # Check for action flags sent by the dialog.
  if 'action' in response['output']:
    current_action = response['output']['action']
  # User asked what time it is, so we output the local system time.
  if current_action == 'display_time':
    print('The current time is ' + time.strftime('%I:%M:%S %p') + '.')
    speak('The current time is ' + time.strftime('%I:%M:%S %p') + '.')
  # If we're not done, prompt for next round of input.
  if current_action != 'end_conversation':
    user_input = input('>> ')

Currently I can write the speech from keyboard and it works. I want the user input to come from the text generated from the transcribes audio using Google Text to speech. I need to get the data from the recorded audio into the main part of my Python script where it is communicating with the Watson service.

halfer
  • 19,824
  • 17
  • 99
  • 186
ironmantis7x
  • 807
  • 2
  • 23
  • 58
  • 4
    I don't understand, what's wrong with `data = recordaudio()`? – Denziloe Aug 26 '18 at 21:27
  • @Denziloe my program for some reason doesn't see data when I set to record audio. Perhaps I should post the code in full? – ironmantis7x Aug 26 '18 at 22:39
  • 1
    No, you should work out what your actual problem and question is. – Denziloe Aug 26 '18 at 22:57
  • data = recordaudio() was the actual solution that worked. Thank you @Denziloe – ironmantis7x Aug 28 '18 at 05:01
  • No problem. This is very basic Python so you should read the official Python tutorial rather than guessing how to code. – Denziloe Aug 28 '18 at 09:33
  • Aside: there was a problem with the presentation of this question that may be relevant to your current questions and how they are being asked. Here it looks like a question was asked, it got an answer, and then it was substantially modified. My first thought, whenever this happens, is whether the answer has been invalidated by the edit. This is important because Stack Overflow is intended to be a collection of helpful Q&A that is useful for many readers, and not just question authors. – halfer Apr 12 '20 at 12:19
  • If a major question change invalidates an answer, then the answer would have to be deleted, since we cannot have a situation where an answer does not answer the question in its current state. To avoid being unfair to an answer author, and to ensure that their time has not been wasted, another solution to this problem is to roll back a question edit so that it matches an answer. – halfer Apr 12 '20 at 12:20
  • In future, if the supply of an answer were to prompt the substantial modification of a question, then either the amendment should go in an update, so the question as it was asked at the time of answering is captured. Or, if the addendum is not trivial, it is probably best as a new question. That will help us maintain our shared goal here, which is the creation of Q&A posts that are still useful for years to come, for many readers. – halfer Apr 12 '20 at 12:22

2 Answers2

1

There are some subtleties that are best explored through examples, which I will provide below. An important keyword is 'global'. You can use the keyword 'global' inside a function to ensure that Python knows you want to work with the global variable with that name, and not declare a local variable.

Lists and other collections are interesting, because Python can understand when you are trying to modify an existing collection rather than declare a new one. An example of this is included in the demo code.

# These are global variables accessible anywhere in the script.
# They do not belong to any function or class.
my_string = ""
my_list = [1]


def a():
    return "a"


def b():
    my_string = "b" # this *is not* the global my_string


def c():
    global my_string
    my_string = "c" # this *is* the global my_string


def d():
    my_list = [7] # this *is not* the global my_list


def e():
    my_list[0] = 4 # this *is* the global my_list


def f():
    global my_list
    my_list = [1, 2, 3] # this *is* the global my_list


my_string = a()
print(my_string) # my_string has been assigned "a"


b()
print(my_string) # my_string is still "a"


c()
print(my_string) # my_string is now "c"


d()
print(my_list) # my_list is still [1]


e()
print(my_list) # my_list is now [7]


f()
print(my_list) # my_list is now [1, 2, 3]
code beginner
  • 285
  • 3
  • 14
0

So, the solution by @Denziloe was correct with a few more additions.

In the main I put a while loop for while the microphone is active, I then initiated user input to start the service connection. Then I put in another loop with data = recordaudio() and set the user input to data.

It now works.

Thanks everyone.

ironmantis7x
  • 807
  • 2
  • 23
  • 58