-1

I'm working on this project of speech recognition and text to speech. I got three scripts, one is the Form.cs, other is the script for the text to speech (Voice.cs) and another one for other methods Auxiliary.cs. the Voice.cs has the variable SpeechSynthesizer synth = new SpeechSynthesizer(); as normal.

And then I have this void:

public void Say(string speech)
{
   synth.SpeakAsync (speech);
}

When I call the Voice.Say(string) in the Form.cs script it works good, when I call it from the Auxiliary.cs it throws NullReferenceException in synth.

Why is this happening? I mean, the form script is calling it in the exact same way as the Auxiliary.cs

Sorry if this question already exists, I searched for it all over the site but yet, came up with nothing.

EDIT: These are the codes.

    //Form1.cs
    public partial class Form1 : Form
    {
        public Auxiliary auxiliary;
        public Voice voice;
        public void Form1_Load ()
        {
             voice = new Voice ();
             auxiliary = new Auxiliary();
             voice.Say("Hi, Patrick");
        }
    }

    //Auxiliary.cs
    public class Auxiliary
    {
        public Voice voice;
        public void Start()
        {
            voice = new Voice();
            voice.Say("Hi");
        }
    }

  //Voice.cs
  public class Voice
  {
      public SpeechSynthesizer synth;
      public void Start()
      {
          synth = new SpeechSynthesizer();
      }
      public void Say(string speech)
      {
          synth.SpeakAsync(speech);
      }
  }
  • 2
    Can you show us where your `synth` object is defined? – GantTheWanderer Jan 14 '17 at 00:48
  • 1
    It throws a null reference exception *in* synth? As in the method where you are using synth but inside the synth class while trying to run SpeakAsync? Can't you just use a debugger to confirm what is null and then check why the code you are expecting to make it not null is not running? As it is you really haven't given us enough to go on to guess why you haven't correctly set something to be not null. – Chris Jan 14 '17 at 00:57
  • 4
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Chris Jan 14 '17 at 00:57
  • I gave more details in the last edit, I have no idea of what's wrong. – Patrick Junio Jan 14 '17 at 01:12
  • In the `Voice.Say` method, you have a `voice.SpeakAsync(speech);`. I don't see how this could even compile, since `voice` is not declared. Did you mean `synth.SpeakAsync(speech);`? Btw.: If that is indeed an async method, you shouldn't call it synchronously but asynchronously: `await synth.SpeakAsync(speech);`. – stakx - no longer contributing Jan 14 '17 at 01:22
  • I meant synth.SpeakAsync(speech), sorry. and it works when I call it from the auxiliary.cs. – Patrick Junio Jan 14 '17 at 01:23

1 Answers1

0

It is a good practice add constructors with appropriate arguments to the classes.

Using Constructors (C# Programming Guide)

In your case, method Voice.Start() is never called, therefore there is none instance of synth object.

// Voice.cs
public class Voice
{
    public SpeechSynthesizer synth;

    public Voice()
    {
        Start();
    }

    public void Start()
    {
        synth = new SpeechSynthesizer();
        synth.SetOutputToDefaultAudioDevice();
    }

    public void Say(string speech)
    {
        synth.SpeakAsync(speech);
    }
}
McNets
  • 8,988
  • 2
  • 25
  • 49
  • it's being called by the form1.cs, i didn't write it in the question though. Thank you for your tip "Using Constructors" i will start to use them now. I solved my problem Instantiating the synth in the void Say, so it's going to be null. I don't know if this is expensive for the computer but it solved my problem. – Patrick Junio Jan 14 '17 at 02:18
  • OMG I did what you said, used a constructor in the Voice.cs public Voice () { synth = new SpeechSynthesizer(); synth.SelectVoice("IVONA 2 Brian"); synth.SetOutputToDefaultAudioDevice(); } Thank you so much dude!! – Patrick Junio Jan 14 '17 at 02:28
  • 1
    I wouldn't say it's good practice to add default constructors. It's good practice to add constructors with *appropriate* arguments. If one with an empty argument list is appropriate, then that's good, but if it wasn't appropriate for the class then it would be a bad practice. – Jon Hanna Jan 14 '17 at 03:00