martedì 6 febbraio 2007
In un post di qualche giorno fa ho accennato al fatto che il riconoscimento vocale di Speech Server .NET è basato su grammatiche. Una grammatica, nella sua concezione più semplice, è costituita dall'elenco dei termini che il motore di ASR è in grado di riconoscere. Utilizzando il .NET Framework 3.0 è semplicissimo definire una grammatica e utilizzarla per riconoscere i comandi pronunciati dall'utente:
1 using (SpeechRecognitionEngine sre = new SpeechRecognitionEngine())
2 {
3 Choices choices = new Choices();
4 choices.Add("One");
5 choices.Add("Two");
6 choices.Add("Turn on the light");
7 choices.Add("Turn off the light");
8 //Altri termini da riconoscere...
9
10 Grammar grammar = new Grammar(choices.ToGrammarBuilder());
11 sre.LoadGrammar(grammar);
12 sre.SetInputToWaveStream(ms);
13
14 RecognitionResult result = sre.Recognize();
15 //A questo punto 'result.text' contiene il testo riconosciuto.
16 }
La variabile ms, utilizzata nella riga 12, è un oggetto di tipo MemoryStream che contiene il parlato da riconoscere: in questo esempio, infatti, si suppone che l'input dell'utente sia stato precedemente registrato e copiato in memoria.
La definizione di una grammatica richiede la creazione di un oggetto di tipo Choices, che deve essere popolato specificando i termini da riconoscere. Nel costruttore della classe SpeechRecognitionEngine è possibile indicare la lingua del riconoscitore che si intende utilizzare. Il riconoscimento vocale è disponibile solo nelle seguenti versioni di Windows Vista: inglese, francese, tedesco, spagnolo, giapponese e cinese (tradizionale e semplificato). Se si utilizza Windows XP, invece, installando lo Speech API 5.1 SDK si ha a disposizione un sistema di ASR nelle lingue inglese, giapponese e cinese semplificato.
Modificando opportunamente il file web.config è possibile specificare quale pagina deve essere visualizzata quando si verificano errori durante l'esecuzione di un'applicazione ASP .NET. Questo articolo spiega in dettaglio tutti i passaggi della procedura; gli esempi inclusi sono disponibili sia per VB .NET sia per C#-
In its continued commitment to interoperability, Microsoft provides a Java Database Connectivity (JDBC) driver for use with SQL Server 2005. The SQL Server 2005 JDBC Driver [...] provides access to SQL Server 2000 and SQL Server 2005 from any Java application, application server, or Java-enabled applet. This driver is a Type 4 JDBC driver that provides database connectivity through the standard JDBC application program interfaces (APIs) available in J2EE (Java2 Enterprise Edition).
Per il download, fare clic qui.
E' stata da poco rilasciata la CTP di Febbraio di "WPF/E". Le novità introdotte sono riassunte qui, mentre il download è disponibile su questa pagina. La nuova release finalmente supporta FireFox 2.0 su piattaforma Machintosh.
Per chi preferisce avere applicazioni nella propria lingua, è stata resa disponibile la versione italiana di WinRAR 3.70 beta 3. Il download è raggiungibile a partire da questa pagina.
Ho notato una incoerenza... Il download del Windows Mobile 5.0 SDK per Pocket PC richiede il controllo di autenticità di Windows, mentre la versione per Smartphone no
. La cosa ancora più strana è che il Windows Mobile 5.0 Developer Resource Kit, che contiene sia la versione per Pocket PC, sia quella per Smartphone, può essere scaricato senza alcuna verifica di autenticità
. Che sia una svita di Microsoft?
Tra gli esempi contenuti nel Windows Mobile 5.0 SDK per Pocket PC e per Smartphone ce n'è uno, molto interessante, che mostra come utilizzare il GPS in un'applicazione C#. Una delle classi di questo esempio, tuttavia, ha un piccolo bug: la descrizione del problema e la sua soluzione sono illustrati in questo post.
Qualche giorno fa ho parlato del CompactFormatter, una class library che aggiunge la serializzazione binaria al .NET Compact Framework. In questo momento lo sto utilizzando per un progetto ed ho riscontrato un problema: se tento di serializzare una classe ereditata, i campi della classe base non vengono serializzati. Facendo un'esecuzione passo-passo, si scopre che il problema risiede nella seguente riga di codice, contenuta nel file ClassInspector.cs:
FieldInfo[] array = type.GetFields(BindingFlags.Public| BindingFlags.NonPublic |
BindingFlags.Instance|BindingFlags.DeclaredOnly);
Il metodo
Type.GetFields, utilizzato per recuperare i campi della classe che si sta serializzando, è richiamato con il flag
BindingFlags.DeclaredOnly che, come riporta
MSDN,
search only the fields declared on the Type, not fields that were simply inherited. Di conseguenza, per ottenere una serializzazione di tutti i membri della classe, compresi quelli ereditati, è sufficiente eliminare questo tag, in modo che l'istruzione sopra riportata diventi:
FieldInfo[] array = type.GetFields(BindingFlags.Public| BindingFlags.NonPublic |
BindingFlags.Instance);
La gestione delle connessioni ricopre un ruolo fondamentale in ogni applicazione per dispositivi mobili: spesso è necessario sapere quali sono le reti disponibili e identificarne le caratteristiche. Purtroppo il .NET Compact Framework non offre un supporto nativo per questi task. In una situazione del genere ci viene in aiuto lo Smart Device Framework: esso, infatti, fornisce una serie di classi mediante le quali è possibile gestire le proprietà delle reti identificate, ricevere notifiche quando viene individuata una nuova connessione, ecc. A questo indirizzo è disponibile una breve introduzione all'argomento, corredata da un esempio scritto in VB .NET.
Cosa succede quando un metodo che prende in ingresso uno Stream termina la sua esecuzione? Lo stream deve rimanere aperto oppure essere chiuso? In alcuni casi, è corretto che esso venga chiuso: ad esempio, se lo stream in questione è un FileStream, in questo modo all'uscita del metodo si ha a disposizione un file correttamente salvato su disco. In altre situazioni, però, lo stream dovrebbe rimanere aperto, perché si vogliono fare alcune elaborazioni sui dati che sono stati riversati in esso; pensiamo al MemoryStream: dopo che il metodo vi ha copiato il suo output, si potrebbe voler accedere ad esso per recuperare l'array di byte corrispondente ed inviarlo, ad esempio, su una connessione TCP.
La seguente situazione, quindi, potrebbe essere fonte di problemi: si utilizza il metodo di una libreria di terze parti, di cui non si ha il codice sorgente, il quale prende in ingresso uno stream e lo chiude al termine della sua elaborazione, ma in realtà si avrebbe bisogno che rimanesse aperto. In un caso del genere, per aggirare il problema è possibile estendere il tipo contenente lo stream che si sta utilizzando, ridefinendo il suo metodo Close:
namespace System.IO
{
class ClosableMemoryStream : MemoryStream
{
private bool _closeable;
public bool Closeable
{
get { return _closeable; }
set { _closeable = value; }
}
public ClosableMemoryStream()
: base()
{
_closeable = true;
}
public override void Close()
{
if (_closeable)
base.Close();
}
public void ForceClose()
{
base.Close();
}
}
}
In questo esempio si tratta di un MemoryStream. La proprietà Closable specifica se lo stream deve essere chiuso quando si richiama il suo metodo Close. Per evitare che lo stream venga chiuso dal metodo della libreria, è sufficiente passare a quest'ultima un oggetto di tipo ClosableMemoryStream (anziché MemoryStream), dopo aver impostato la sua proprietà Closable su false: quando sarà richiamato il metodo Close, verrà eseguito il suo override, quindi lo stream in realtà rimarrà aperto. Dopo aver effettuato tutte le elaborazioni necessarie, per la chiusura vera e propria è necessario richiamare il metodo ForceClose.
A
questo indirizzo è disponibile un add-in per
Microsoft Word che consente di aprire e salvare documenti nel formato
Open Document (ODF). L'add-in richiede il .NET Framework 2.0 ed è compatibile con le versioni XP, 2003 e 2007 di Word.