4

I have writtten an application using SpeechSynthesizer which reads out text of a TextBox. In my ViewModel I have created a Single instance of that class and overridden Finalize method for disposal. When I paste some text in the TextBox and keep clicking on buttons I see the memory usage keeps increasing. In my application I have four buttons Play, Pause, Resume and Stop/Clear. In my ViewModel I have following Code

let ss = new SpeechSynthesizer()
let state = self.Factory.Backing( <@ self.State @>, ss.State)
let inputText = self.Factory.Backing(<@ self.InputText @>, "") 

let canPlay() = self.State <> SynthesizerState.Speaking && 
                self.State <> SynthesizerState.Paused && 
                not(String.IsNullOrWhiteSpace(self.InputText))

let canPause() = self.State = SynthesizerState.Speaking 
let canResume() = self.State = SynthesizerState.Paused 
let canStop() = not(String.IsNullOrWhiteSpace(self.InputText))

let play() = ss.SpeakAsync(self.InputText) |> ignore
             self.State <- SynthesizerState.Speaking 

let pause() = ss.Pause(); self.State <- SynthesizerState.Paused 
let resume() = ss.Resume(); self.State <- SynthesizerState.Speaking
let stop() = if ss.State = SynthesizerState.Paused then ss.Resume()   
             ss.SpeakAsyncCancelAll()
             self.State <- SynthesizerState.Ready 
             self.InputText <- "" 
do
    self.DependencyTracker.AddPropertyDependencies( <@ self.Play @>, [ <@@ self.InputText @@> ; <@@ self.State @@> ] )
    self.DependencyTracker.AddPropertyDependency( <@ self.Pause @>, <@ self.State @> )
    self.DependencyTracker.AddPropertyDependency( <@ self.Resume @>, <@ self.State @>  )
    self.DependencyTracker.AddPropertyDependency( <@ self.Stop @>, <@ self.InputText @> )

member self.InputText with get() = inputText.Value and set(v) = inputText.Value <- v 
member self.State with get() = state.Value and set(v) = state.Value <- v

member self.Play = self.Factory.CommandSyncChecked(play, canPlay)
member self.Pause = self.Factory.CommandSyncChecked(pause, canPause)
member self.Resume = self.Factory.CommandSyncChecked(resume, canResume)
member self.Stop = self.Factory.CommandSyncChecked(stop, canStop)

override self.Finalize() = ss.Dispose()

and in Xaml

<TextBox AcceptsReturn="True" TextWrapping="Wrap" 
             Text="{Binding InputText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"                 
             VerticalScrollBarVisibility="Auto"/>
<StackPanel Grid.Column="1" Margin="5">
        <Button Content="Play" Command="{Binding Play}" />
        <Button Content="Resume" Command="{Binding Resume}" Margin="0 5 0 0"/>
        <Button Content="Pause" Command="{Binding Pause}" Margin="0 5 0 0"/>
        <Button Content="Stop/Clear" Command="{Binding Stop}" Margin="0 5 0 0"/>
</StackPanel>

Is there anything wrong with my code?

FoggyFinder
  • 2,230
  • 2
  • 20
  • 34
  • @FoggyFinder To solve a problem it is necessary to review ... I think. –  Dec 02 '16 at 12:32
  • 2
    So you have memory leaks due to some reasons. if you use any com objects, they can create some memory leaks. Also, you can check your Factory objects – Ugur Dec 02 '16 at 14:08
  • 4
    Might be https://connect.microsoft.com/VisualStudio/feedback/details/664196/system-speech-has-a-memory-leak which allegedly can be resolved by downloading newest [Microsoft Speech Platform](https://www.microsoft.com/en-us/download/details.aspx?id=27225) – CaringDev Dec 02 '16 at 15:41
  • Thanks @CaringDev! I had to add `ss.SetOutputToDefaultAudioDevice()` in do binding to make it work. Is there any male TTS voice? –  Dec 02 '16 at 19:57

0 Answers0