Wolne wczytywanie tekstu po użyciu SpeechSynthesizer.Speak

0

Witam. Wczytuję tekst do labela, poźniej program go czyta, kliknięcie buttona zmienia tekst w labelu i znów jest czytany. Niestety czytanie tego tekstu sprawia, że pojawianie kolejnego tekstu w labelu nie jest zbyt płynne, a czasem jakby się zacinało. Czy można to jakoś poprawić, aby działo płynnie? Bez czytania przejście działa płynnie.

        public void sprawdzSposobOdtwarzaniaDzwieku(int index, ComboBox cBSposobOdtwarzaniaDzwieku,ComboBox cBdzial, List<string> listaSlowOg)//metoda sprawdzająca w jaki sposób odtworzyć dźwięk
        {
            if (cBSposobOdtwarzaniaDzwieku.SelectedItem != null)
            {
                if (cBSposobOdtwarzaniaDzwieku.SelectedIndex == 0)
                    odczytajAudio(index, cBdzial);
                else if (cBSposobOdtwarzaniaDzwieku.SelectedIndex == 1)
                    odczytajNagranieSyntezator(listaSlowOg[index]);
            }
            else
                MessageBox.Show("Proszę wybrać sposób odtwarzania nagrań.", "Komunikat");
        }

        private void odczytajNagranieSyntezator(string text)//metoda czytająca słowo
        {
            SpeechSynthesizer synth = new SpeechSynthesizer();
            try
            {
                synth.Speak(text);
            }
            catch (Exception)
            {
                MessageBox.Show("Zainstaluj dowolny syntezator mowy.", "Komunikat");
            }
            finally
            {
                synth.Dispose();
            }
        }
 

Tutaj dodam programik, aby mogliście sprawdzić o co chodzi. Wybieramy Syntezator mowy i KoloryAng.

0

Wątki?

0
Thread trd = new Thread(new ThreadStart(this.nagrania.sprawdzSposobOdtwarzaniaDzwieku));
trd.IsBackground = true;
trd.Start();
 

Dostaję błąd:

Error 1 No overload for 'sprawdzSposobOdtwarzaniaDzwieku' matches delegate 'System.Threading.ThreadStart' C:\Users\Marcin\documents\visual studio 2010\Projects\Voc\Voc\Form1.cs 103 45 Voc

0

I słusznie, że go dostajesz. Sygnatura metody sprawdzSposobOdtwarzaniaDzwieku nie pasuje do delegata ThreadStart, który przyjmuje metody bezparametrowe. Poczytaj o ParameterizedThreadStart.

0

Dzięki somekind, znalazłem, ale pojawił się kolejny problem to mam w Form1.cs

 
        private void buttonWprowadzenieDalej_Click(object sender, EventArgs e)
        {
            if (cBdzial.SelectedItem != null)
            {
                index++;
                if (index < listaSlowObcych.Count)
                {
                    wyswietlanie.wyświetlDaneWprowadzenie(listaSlowObcych, listaSlowPolskich, index, lSlowoObce, lSlowoPl, lWprowadzenieLiczbaSlow);
                    wyswietlanie.ileSlowZaprezentowano(listaSlowPolskich, index, lWprowadzenieLiczbaSlow);
                    ThreadStart starter2 = delegate { new Nagrania().sprawdzSposobOdtwarzaniaDzwieku(index,cBdzwiek,cBdzial,listaSlowObcych); };
                    new Thread(starter2).Start();
                    
                }
                else
                {
                    index = 0;
                    lWprowadzenieLiczbaSlow.Text = null;
                }
            }
        }

Klasa Nagrania

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Synthesis;
using System.Windows.Forms;
using System.IO;
using System.Media;

namespace Voc
{
    public class Nagrania
    {
        //**Sposoby odtwarzania Nagrań***********************************************
        public void sprawdzSposobOdtwarzaniaDzwieku(int index, ComboBox cBSposobOdtwarzaniaDzwieku,ComboBox cBdzial, List<string> listaSlowOg)//metoda sprawdzająca w jaki sposób odtworzyć dźwięk
        {
            if (cBSposobOdtwarzaniaDzwieku.SelectedItem != null)
            {
                if (cBSposobOdtwarzaniaDzwieku.SelectedIndex == 0)
                        odczytajAudio(index, cBdzial);
                else if (cBSposobOdtwarzaniaDzwieku.SelectedIndex == 1)
                {
                    odczytajNagranieSyntezator(listaSlowOg[index]);
                }
            }
            else
                MessageBox.Show("Proszę wybrać sposób odtwarzania nagrań.", "Komunikat");
            }

        private void odczytajNagranieSyntezator(string text)//metoda czytająca słowo
        {
            SpeechSynthesizer synth = new SpeechSynthesizer();
            try
            {
                synth.Speak(text);
            }
            catch (Exception)
            {
                MessageBox.Show("Zainstaluj dowolny syntezator mowy.", "Komunikat");
            }
            finally
            {
                synth.Dispose();
            }
        }
        //metoda odtwarzająca nagrania
        private void odczytajAudio(int indexAudio, ComboBox cBDzial)
        {
            if (cBDzial.SelectedItem != null)
            {
                string filename = System.Environment.CurrentDirectory.ToString() + "\\" + cBDzial.SelectedItem.ToString() + "Audio" + "\\" + indexAudio + ".wav";
                DirectoryInfo di = new DirectoryInfo(System.Environment.CurrentDirectory.ToString() + "\\" + cBDzial.SelectedItem.ToString() + "Audio");
                if (di.Exists)
                {
                    try
                    {
                        SoundPlayer sound = new SoundPlayer(filename);
                        sound.Play();
                    }
                    catch
                    {
                        //MessageBox.Show("Nie znaleziono wszystkich nagrań", "Błąd aplikacji");


                    }
                    finally
                    {
                        indexAudio = 0;
                    }
                }
            }
        }
        //****************************
    }
}

Treść błędu:
Cross-thread operation not valid: Control 'cBdzwiek' accessed from a thread other than the thread it was created on.

0

No i słusznie, nie wolno odwoływać się do kontrolek GUI z innych wątków niż wątek GUI.
Poczytaj How To: Make Thread-Safe Calls to Windows Forms Controls.

1 użytkowników online, w tym zalogowanych: 0, gości: 1