Visualizzazione post con etichetta WPF. Mostra tutti i post
Visualizzazione post con etichetta WPF. Mostra tutti i post

domenica 29 maggio 2016

Dettatura in italiano con Cortana

Sebbene quella del riconoscimento vocale sia ormai una tecnologia mainstream, il suo utilizzo è ancora piuttosto scarso a causa di un limite culturale o, più probabilmente, per la mancanza di interfacce vocali ben fatte.
Android e Apple Ios hanno i propri sistemi di dettatura integrati così come Windows, ma fino a Windows 7 l'unico modo per dettare in Italiano con i sistemi operativi Microsoft era installare un software commerciale come Dragon NaturallySpeaking.
Con Cortana e Windows 10 siamo passati alla seconda generazione dei motori di riconoscimento vocale, grazie all'utilizzo di modelli basati sulle reti neurali profonde (DNN).
Microsoft ha reso disponibile il riconoscimento vocale in decine di lingue, ma mancano le applicazioni che lo utilizzano tant'è che a oggi è possibile solamente dettare degli SMS con Windows phone oppure rivolgere delle domande a Cortana. Dettare delle email o un documento in Word è possibile in potenza ma di fatto manca ancora l'integrazione con Cortana.
Eppure le API ci sono. Basta avere Windows 10 e un collegamento a internet perché Cortana trascriva la nostra voce in tempo reale.
Le API di Cortana sono API WinRT, cioè pensate per le App Windows Store ma, esattamente come descritto nel post per le API OCR, è possibile utilizzarle in una normale applicazione desktop.
Qui un semplice progetto WPF che integra le API Windows.Media.SpeechRecognition con cui potrete giudicare l'accuratezza di Cortana.
Richiede Windows 10, l'accesso a Internet e l'input audio microfonico.
Quando terminate di parlare premete il pulsante Stop altrimenti il sistema produrrà un Timeout.
E qui l'esempio ufficiale di Microsoft

Update 23/06/2017: addin Office per la dettatura

domenica 24 luglio 2011

How to animate an image in MVVM

I want to design a "tableau de bord" with some indicators blinking or animating as soon as a boolean condition is true.
The indicators are simple images, the blinking is obtained changing the image opacity in a Storyboard.

<Storyboard x:Key="BlinkingAnimation">
  <DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)"    
    BeginTime="0:0:0" Duration="0:0:0.5"    
    From="1.0" To="0.0" RepeatBehavior="Forever" AutoReverse="True"/>
</Storyboard>

The animaton will start on a DataTrigger bound to a Property defined in the ViewModel


First recipe: just edit the style of the Image in the XAML

<Image Source="/MvvmBlinkingImage;component/Images/favorite.png" >
  <Image.Style>
     <Style>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Property1}" Value="true">
          <DataTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource BlinkingAnimation}" x:Name="blink"/>
          </DataTrigger.EnterActions>
          <DataTrigger.ExitActions>
            <StopStoryboard BeginStoryboardName="blink" />
          </DataTrigger.ExitActions>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Image.Style>
 
</Image> 

Second recipe: Create a custom control inherited from Image. The control registers a dependency property to bind to the DataTrigger


public class AnimatedImage : Image
{
        public static DependencyProperty IsBlinkingProperty =
            DependencyProperty.Register("IsBlinking", typeof(bool), typeof(AnimatedImage));
 
        public bool IsBlinking
        {
            get { return (bool)base.GetValue(IsBlinkingProperty); }
            set { base.SetValue(IsBlinkingProperty, value); }
        }
}

Now add a new style to a DictionaryResource for the new AnimatedImage control:


<
Style x:Key="AnimatedImageStyle" TargetType="{x:Type uc:AnimatedImage}">
  <Style.Triggers>
    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsBlinking}" Value="true">
      <DataTrigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource BlinkingAnimation}" x:Name="blink"/>
      </DataTrigger.EnterActions>
      <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="blink" />
      </DataTrigger.ExitActions>
    </DataTrigger>
  </Style.Triggers>
</Style>   

Please note that IsBlinking is a property of AnimateImage and not of the ViewModel, so it is Necessary override the DefaultContext with RelativeSource Self.Here an useful link on WPF binding: http://www.nbdtech.com/Free/WpfBinding.pdf

Eventually use the AnimateImage control and AnimatedImageStyle in the XAML:

<uc:AnimatedImage IsBlinking="{Binding Property1}" Style="{StaticResource AnimatedImageStyle}" Source="/MvvmBlinkingImage;component/Images/favorite.png" />



giovedì 21 luglio 2011

Detecting USB microphone insertion/removal in C# .Net 4.0 WPF

I'm working on a C# .Net 4.0 WPF project that must detect the insertion or removal of an USB microphone.
The code should be implemented in a C# class library.
Since .Net 4.0 doesn't have classes able to detect the insertion or removal of an USB device, the solution is hooking the message WM_DEVICECHANGE, then find out which device changed in order to be sure that the device is the one desired and not some other device.
The first issue to solve is that we don't have any hWnd handle in a class library, so we need to create a fake window in order to hook his window procedure:


HwndSource hwndSource = new HwndSource(0, 0, 0, 0, 0, "fake", IntPtr.Zero);
if (hwndSource != null)  //Attaching to window procedure
    hwndSource.AddHook(new HwndSourceHook(this.hwndSourceHook));

//the window procedure
IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{
    if (msg == WM_DEVICECHANGE)   
   {
      if ((int)wParam == DBT_DEVICEARRIVAL)
     {   
        DEV_BROADCAST_DEVICEINTERFACE info = (DEV_BROADCAST_DEVICEINTERFACE)   
Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_DEVICEINTERFACE));   
      }   
      else if ((int)wParam == DBT_DEVICEREMOVECOMPLETE)
     {
      }
      else if ((int)wParam == DBT_DEVNODES_CHANGED)
     {
     }
  }  
  return IntPtr.Zero;
}


The second problem is to identify the device by the GUID class.
Several microphones by Philips, Olympus or Dictaphone are multicomposite devices.
It means that when you plugin the microphone you get 5 or 6 WM_DEVICECHANGE messages.
So it is preferable to filter the device class using the RegisterDeviceNotification API.

DEV_BROADCAST_DEVICEINTERFACE notificationFilter = new DEV_BROADCAST_DEVICEINTERFACE();
int size = Marshal.SizeOf(notificationFilter);
notificationFilter.dbcc_size = size;
notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
notificationFilter.dbcc_reserved = 0;
notificationFilter.dbcc_classguid = new Guid(MediaClassID).ToByteArray();
IntPtr buffer = IntPtr.Zero;
buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(notificationFilter, buffer, true);
IntPtr result = RegisterDeviceNotification(this._hwndSource.Handle, buffer, (Int32)(DEVICE_NOTIFY.DEVICE_NOTIFY_WINDOW_HANDLE));

The class guid are stored in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses
If you want find out the class guid of your device, use the parameter DEVICE_NOTIFY_ALL_INTERFACE_CLASSES in RegisterDeviceNotification API, plug in the device into the USB port and read the guid in the DEV_BROADCAST_DEVICEINTERFACE structure.

I found out the following classes used by USB microphones:
KSCATEGORY_CAPTURE = "{65E8773D-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_AUDIO = "{6994AD04-93EF-11D0-A3CC-00A0C9223196}"

Here attached a MVVM project using the USBDetector class

WPF

Non sono un serio sviluppatore ma nella mia attività mi tocca creare scripts e applicazioni per automatizzare l'attività di ufficio. Negli ultimi 20 anni ho utilizzato principalmente come strumenti di programmazione C++ e MFC. Quando l'anno scorso ho visto in azione .Net 4.0 e WPF, mi è uscito spontaneamante un Sokka!
Ho intrapreso un percorso autoformativo per uscire dalla caverna trovando particolarmente utili i webcast di Corrado Cavalli, senza dubbio il migliore nella sua categoria.
Molto interessanti i tutorial di channel9 e gli eventi tecnici di TechEd.
Aggiungendo un pizzico di patterns e toolkits (Model View ViewModel, Dependendy Injection, Inversion of Control) come MVVM Light e Unity conto di disporre di un framework che rimarrà attuale per i prossimi 20 anni.