Windows Dev. Site

Windows Store App で音声合成

Windowsストアアプリを開発中ですが、Windows 8.1から Windows.Media.SpeechSynthesis が新たに加わるようです。これでテキストの音声読み上げができるようになったということで試してみました。

http://msdn.microsoft.com/en-us/library/windows/apps/windows.media.speechsynthesis.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

環境 : VisualStudio 2013 Preview / Windows 8.1 Preview / VirtualBox 4.2.16 / Mac OS X 10.7.5

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.SpeechSynthesis;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace csStoreXaml1
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {

            // The media object for controlling and playing audio.
            MediaElement mediaElement = new MediaElement();

            // The object for controlling the speech synthesis engine (voice).
            var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();

            // Generate the audio stream from plain text.
            SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("クロスフレーム in 愛知県名古屋市");

            // Send the stream to the media object.
            mediaElement.SetSource(stream, stream.ContentType);
            mediaElement.Play();

        }
    }
}

日本語にも対応しているのは嬉しいことです。「愛知県名古屋市」も問題なく聞き取れました。
ストアアプリの新しい企画を考える際、幅が広がりそうです。

C#, Lua連携

Luaという汎用スクリプト言語ですが、最近いろんなところで目にするようになりました。ネットワークツールのNmap、インメモリDBのRedis、Vocaloidやゲームなど、幅広いところで使われています。VisualStudioのNuGetにもSharpLuaというパッケージがあったので、これを使ってC#との相互呼び出しをやってみようと思いました。
しかし、C#からはLuaを使えるのですが、その逆がうまくいかなかったので、LuaInterface(http://code.google.com/p/luainterface/)というものを使いました。

環境 : VisualStudio 2010 / Windows 7
C#コンソールアプリケーション


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuaInterface;
using System.Reflection;

namespace csConsLua
{
    class Program
    {
        LuaInterface.Lua lua = new LuaInterface.Lua();

        static void Main(string[] args)
        {
            Program p = new Program();

            p.start();

            Console.ReadLine();
        }
        public void csFunc(string msg)
        {
            Console.WriteLine("msg : " + msg);
        }
        public void start()
        {
            lua.DoString("function luaFunc(msg) return string.format(\"msg : %s\", msg) end");

            object[] o = this.lua.GetFunction("luaFunc").Call("from C#");
            string s = (string)o[0];

            Console.WriteLine(s);
            
            lua.RegisterFunction("csFunc", this, GetType().GetMethod("csFunc"));

            lua.DoString("csFunc(\"from Lua\")");

        }
    }
}

設定としては、http://luainterface.googlecode.com/files/LuaInterface_2.0.3.7z を解凍してできたdllを、「参照の追加」で読み込み、プロジェクトのプロパティで、「対象のフレームワーク」を ‘.Net Framework 3.5 Client Profile’ にしました。
これを実行した出力は、

msg : from C#
msg : from Lua

となります。
また、統合開発環境には、ZeroBraneStudio(https://github.com/pkulchenko/ZeroBraneStudio)というものがあり、学習に便利だと思いました。

次は、Redis/Azureあたりをやってみたいと思っています。

Haskell / Windows

Haskellは以前勉強しましたが、使うことがないこともあってまったく身に付きませんでした。関数型言語はF#を学習中ですが、いろいろと勉強しているとHaskellに関するサンプルや情報が多いことを感じ、すぐテストできる環境を用意しておいた方がいいと思い、セットアップしてみました。

http://neue.cc/2010/01/04_233.html

このサイトをみると、IDEにはLeksahがよさそうだ、ということでインストールしてみました。
Leksahの前に、Haskell Platformをインストールする必要があります。
HaskellコンパイラGHCのバージョンは、7.6.3ですが、leksah-0.12.0.3-ghc-7.4.1.exe(これが最新なので)を使いました。

Leksahを起動後、Package->Newから、Create Folderでフォルダを作りますが、これがイコールプロジェクト名となります。フォルダを作成してOpenすると、Package設定がでてくるので、Executablesを選択して、ExecutableNameをクリックしてSaveします。
Lekp

デフォルトで以下のような、”Hello World”を表示するだけのサンプルコードが生成されるので、これを
- Configures the package
- Builds the package
- Runs the package
と順に、ツールバーから実行します。するとLog Windowに”Hello World”が表示されます。
hcode

これでとりあえず動作確認をしておいて、目的のプログラムを動かしてみます。
ファイルコンバータ的なものをつくることが多くなりそうなので、大文字変換するものを試してみました。
Lek0s
あとエディタの面白い機能として、カスタム文字への変換があります。
Configuration->To Candyチェックボックスで、以下の表示切替をできます。

Lek1s

Lek2s

こういうのマニア心をくすぐりますね。ソースは、O’REILLYの”Real World Haskell”から引用しました。
欲を言えば、neueccさんのサイトにあるVisual Haskellのようなものが使えれば、とも期待もしたのですが(VisualStudioで他の言語とリンクできたりできるなどなど)、無理っほいのでここまでとなりました。

Python / Django / WindowsAzure

Pythonの代表的なWebアプリケーションフレームワークであるDjangoをWindowsAzureにデプロイしてみました。
各ツールのバージョンか変わるとセットアップの方法も変わったりしますので、最新のものでテストしてみました。

環境 : VisualStudio 2013 Preview / Windows 8.1 Preview / VirtualBox 4.2.16 / Mac OS X 10.7.5

参考サイト : One of Microsoft’s Best-Kept Secrets – Python Tools for Visual Studio (PTVS) http://www.hanselman.com/blog/OneOfMicrosoftsBestKeptSecretsPythonToolsForVisualStudioPTVS.aspx

プロジェクトの新規作成からPython -> Django Application を選択
ソリューションエクスプローラから、PythonEnvironments右クリック -> Add Virtual Environment

pyvenv

env(Pyton3.3)右クリック->Install Python Package

dangoInst

インストールが無事終了したら、まずはローカルサーバで確認するためInternet Explorer で実行
以下のような画面が表示されます。

djangoApp

WindowsAzureへのデプロイは、前回のSignalRの記事と同様に発行プロファイルをダウンロードしてVisualStudioにインポートします。

http://(作成したWEBサイト).azurewebsites.net/

で、ローカルで確認した同じページが表示されます。

以前違う方法でトライして失敗したためそのままにしていましたが、バージョンが上がって、かなり簡単にDjangoのインストールができるようになりました。

とりあえずここまでメモということで。

SignalR / WindowsAzure

前々回の投稿「ASP.NET SignalR」で、SignalRのテストをIISでしましたが、これをAzureにデプロイしてみたのを備忘録として書きました。

1) manage.windowsazure.comのサイトで、WEBサイトを新規追加
2) ダッシュボードの概要から、発行プロファイルのダウンロード
azureWeb
3) VisualStudo2012のプロジェクト右クリックで、「発行」を選択
4) 2)でダウンロードしたプロファイルをインポート
azureDeploy
インポートをすると自動的に上のような画面になります。
5) 「発行」ボタン押下でブラウザが起動 URL http://****.azurewebsites.net
6) URLをhttp://****.azurewebsites.net/WebFrom1.aspx

これで動作確認できました。

ソースは以下の部分修正しました。

//var connection = $.hubConnection("http://192.168.11.10/test/aspEmptyWebSignalr/signalr/hubs");
var connection = $.hubConnection();

(こういうのメモしておかないと、バージョンアップ等でインターフェイスとか変わったりすると結構つまらないところで悩んだりするんですよね。)

ブラウザは、IE10とFireFoxで試しましたが、WebSocketの通信ではなく、JSONのようでした。AzureのサーバがWebSocket対応でないためでしょうか。

Windowsストアアプリ申請

二つ目のWindowsストアアプリを本日申請しました。前回のリリースでBlogに書きませんでしたので、ストアアプリの開発の方針みたいなものをまとめてみました。

ストアアプリは従来のWindowsアプリケーションとは、大きく様変わりしているので、いろいろとテストをしています。しかしやはり何か目的があった方(形になった方)がより開発のモチベーションもあがるということで、いろんなタイプのアプリケーションを作っていこうと思っています。いまのところの目標は、WindowsAzureとこれからリリースされるであろうWindowsPhone8で何かやってみたいと思っています。

ストアアプリはいろんな言語で開発できますので、いろいろと試す意味でも前回は、JavaScript + SVG、今回はC# + XAMLで開発しました。こんなことを繰り返しながら目標に近づいていけたらと思っています。

リリース済 Clocklavier ピアノで時刻を奏でます icon
申請中 bitlife ライフゲームに編集、保存、サウンド機能を追加してみました StoreLogo
開発中 メッセージアプリ(仮) ローカルネットワークのチャットアプリです。

ストアアプリの情報は、以下サイトをご覧ください。

http://crossframe.iiv.jp/apps/

個人的趣味が強いですが、よろしかったお試しくたざいませ。

ASP.NET SignalR

サーバプッシュのWebテクノロジーはいくつかありますが、ASP.NETで提供される最新の技術であるSignalRを試してみました。
最近いろいろとテストするにあたって感じるのは、記事等を読んで理屈ではわかっていても実際にやってみると環境や設定、バージョン違い等で構築に結構手間取ったりすることがあります。やはり実際に自分でやってみるということは大切だと思うこのごろです。

今回参考にしたのは以下の記事ですが、パケットキャプチャをとるためIIS(ローカル)で動作させました。
http://www.atmarkit.co.jp/ait/articles/1303/19/news099.html ASP.NET SignalR入門(前編)

環境 : VisualStduo 2012 / Windows 8

管理者としてVSを実行
ASP.NET空のWebアプリケーションのプロジェクトを作成
参照設定の追加でNugetパッケージ管理からSignalRを検索してインストール
新しい項目の追加でSignalR Hubクラスを作成 MyHub1.cs
新しい項目の追加でグローバルアプリケーションクラス作成 Global.asax
新しいウェブフォームの追加 WebForm1.aspx, WebForm2.aspx

MyHub1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace aspEmptyWebSignalr.Hubs
{
    [HubName("echo")]
    public class MyHub1 : Hub
    {
        public void Send(string text)
        {
            Clients.All.Receive(text);
        }
    }
}

Global.asax

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Routing;

namespace aspEmptyWebSignalr
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.MapHubs();
        }
    }
}

WebForm1.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="aspEmptyWebSignalr.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <script src="Scripts/jquery-1.6.4.min.js"></script>
  <script src="Scripts/jquery.signalR-1.1.2.min.js"></script>
  <script>
      $(function () {
          var connection = $.hubConnection("http://192.168.11.10/test/aspEmptyWebSignalr/signalr/hubs");
          var echo = connection.createHubProxy("echo");
          echo.on("Receive", function (text) {
              $("#list").append("<li>" + text + "</li>");
          });
          $("#send").click(function () {
              var message = $("#message").val();
              echo.invoke("Send", message).done(function () {
                  $("#message").val("");
              });
          });
          connection.start(function () {
              $("#send").prop("disabled", false);
          });
      })
  </script>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <input type="text" id="message" />
    <input type="button" id="send" value="送信" disabled="disabled" />
    <ul id="list"></ul>
  </div>
  </form>
</body>
</html>

受信のみバージョンもテストしてみました。(送信と受信をわけることによって面白いことができそうです。)
WebForm2.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="aspEmptyWebSignalr.WebForm2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <script src="Scripts/jquery-1.6.4.min.js"></script>
  <script src="Scripts/jquery.signalR-1.1.2.min.js"></script>
  <script>
      $(function () {
          var connection = $.hubConnection("http://192.168.11.10/test/aspEmptyWebSignalr/signalr/hubs");
          var echo = connection.createHubProxy("echo");
          echo.on("Receive", function (text) {
              $("#list").append("<li>" + text + "</li>");
          });
          connection.start();
      })
  </script>
</head>
<body>
  <div>
    <ul id="list"></ul>
  </div>
</body>
</html>

IISにデプロイするときは$.hubConnectionの引数にURLをフルで書く必要があります。(デフォルトだと空)
デプロイは、IISマネージャでDefaultWebSiteの下にディレクトリを作成した後、VSのビルド->Webの発行で、発行方法「ファイルシストム」を選び、ターゲットに作成してディレクトリを指定します。
バケットキャプチャはWireSharkを使い、サーバ側(192.168.11.10)でキャプチャしました。クライアント(192.168.11.12)はFirefoxの最新バージョン(22)です。
captSignalR
送信したテスキトは、”aaaaaaaaaaaa”です。HTTPとはまた違うみたいですね。また調べていきたいです。ちなみにIE7/WindowsXPでも試しましたが、通信できませんでした。(WebSocketに対応していないブラウザだと違うプロトコルでやるのかなと思ったのですが・・まだ他に設定がいるのかも)あとiPhoneのSafariは動作確認しました。

ASP.NETの既存のサービスに追加する形で使うのに、とても便利だと思いました。

C#, Python で R.NET

最近の統計ブームにのって私もいろいろと興味があったので、「R」という統計ソフトを使ってみました。制御系の仕事をしていたときMatlabというシミュレーションソフトを使っていましたが、行列とかが簡単に扱えるインタープリタにとても驚かされました。とても魅力的なソフトなのですがとても高価なため個人では手軽に使えるものではありませんでした。Rのインタプリタを使っていると、そのときの感動がよみがえってきました。
調べてみるとRDotNet(http://rdotnet.codeplex.com/)を使うと、C#からRの機能が使えるということなので、いろいろとテストをしてみました。

環境: R 3.0.0, VisualStudio 2010/ Windows 7

using System;
using System.IO;
using System.Linq;
using RDotNet;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        var envPath = Environment.GetEnvironmentVariable("PATH");
        var rBinPath = @"C:\Program Files\R\R-3.0.0\bin\i386";
        Environment.SetEnvironmentVariable("PATH", envPath + Path.PathSeparator + rBinPath);
        using (REngine engine = REngine.CreateInstance("RDotNet"))
        {
            engine.Initialize();

            StringBuilder command = new StringBuilder();
            commmand.Append(@"x <- 1:10;");
            commmand.Append(@"plot(x);");
            engine.Evaluate(commmand.ToString());
            Console.ReadLine();
        }
    }
}

まず、Rのコマンドラインで試した簡単なプロットをC#からやってみました。しかしこのやり方だと、単にリモート実行しているだけなのであまり意味がないと思い、以下のように修正しました。

class Program
{
    static void Main(string[] args)
    {
        var envPath = Environment.GetEnvironmentVariable("PATH");
        var rBinPath = @"C:\Program Files\R\R-3.0.0\bin\i386";
        Environment.SetEnvironmentVariable("PATH", envPath + Path.PathSeparator + rBinPath);
        using (REngine engine = REngine.CreateInstance("RDotNet"))
        {
            engine.Initialize();

            NumericVector nn = engine.CreateNumericVector(new double[] {1,2,3,4,5,6,7,8,9,10});
            engine.SetSymbol("nn", nn);
            engine.Evaluate("plot(nn)");

            Console.ReadLine();
        }
    }
}

こういったのは、スクリプト言語からの方が使い勝手がいいと思い、.NETでもあるのでIronPythonから呼び出してみようとトライしました。しかしモジュールをうまく読み込んでくれなかったので、普通のPythonに変更しました。しかしこれも、rpy2モジュールが64bitの環境でうまくインストールできなかったので、最終的にMacでテストしました。

sudo pip install rpy2

で簡単にインストールできました。

環境 : R 3.0.1, Python 2.7.1 / MacOSX 10.7.5

import rpy2.robjects as ro
import time

r = ro.r
q = r.seq(0,10);
r.plot(q);

time.sleep(3);

実行結果は以下のプロット画面です。この画面の実行はWindowsのRで行ったものです。

R

IronPythonでやる方法はまた調べたいと思います。

.NET Webフレームワーク Nancy をC#とF#で

.NET 用の軽量Webフレームワーク Nancy をC#とF#でテストしてみました。

以下記事参照
http://shiba-yan.hatenablog.jp/entry/20130509/1368107112「Sinatra ライクな .NET 用軽量 Web フレームワーク「Nancy」を使ってみた 」

SinatraはJRuby/GoogleAppEngineで遊んだことがありますが、とてもシンプルで気にいっていました。.NETフレームワークにもこのようなものが欲しいと思っていたので、この記事をみつけてすぐにいろいろと試そうと思ったのですが、F#でASP.NETを使って何かをつくろうとしていたので、後回しにしていました。しかしASP.NETとF#って、VS2012の環境でまだ環境が十分でないためか、なかなか思った形のものができませんでした。(セルフホストのものはいろいろあるのですが・・)
そのときタイミングよくNancyでF#を使える以下の記事も見つけたので、C#とF#両方あわせて動くものを作ってみました。

http://qiita.com/yohfee/items/1e5908cd720706805c94「F#でNancyをASP.NETでホストする 」

環境 : VisualStudio 2012 / Windows 8
プロジェクト : C# ASP.NET 空のWebアプリケーション に 追加Webフォーム
追加プロジェクト : F#ライブラリ
Library1.fs

namespace Library1
open Nancy
type FsTest() =
    inherit NancyModule()
    do
        base.Get.["/fs"] <- fun _ -> box "Hello Nancy F#"

Nugetで、Nancy追加

WebForm1.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace csAspEmptyWebFsNancy
{
    public class CsTest : Nancy.NancyModule
    {
        public CsTest()
        {
            Get["/cs"] = _ => "Hello Nancy C#";
        }
    }
}

NuGetでNancy,Nancy.Hosting.Aspnet追加

ブラウザで、/cs, /fs とアクセスするとそれぞれの文字列が表示されます。
F#でパラメータを渡すことを試したのですが、いろいろと難しくまたトライしてみたいと思います。(C#は記事にあります)
結構いろいろとテストしたのですが、結局これだけしか公開できないとは・・
まだまだです。

WindowsストアアプリでF#

最近のLINQネタの勢いで、F#に手をだしてしまいました。これまでLisp, Haskell, Clojure, Scalaなどなど関数型言語の勉強はしつつも、なかなか使う機会がないので、まったく身につきませんでした。本ばかりがたまる一方です。そして今度はF#。また同じ運命をたどるかも。
しかし今回は、Windowsストアアプリでも使えるということで、具体的な形になる可能性が高いという期待があります。(最近の流れからして動機としては十分です。)F#だけですべてを作るのではなく、C#から呼び出す形でデータ操作を専門にする使い方なら、かなり実用性があるのではと感じました。
オブジェクト指向言語は、WindowsなどのGUIの出現とともに必要とされ生まれ、そして関数型言語はインターネット時代、CPUマルチコア時代に必要とされ生まれてきたのでは、と思っています。最近の他の言語の傾向を見ていても、その必要性が今まで以上に感じられるようになってきました。
xamlListbox1
サンプルは、C#+XAMLのWindowsストアアプリから、正規表現の部分を記述したF#の関数を読んでいます。
結果は、ListBoxに書き出します。
正規表現の部分は、「実践F#関数型プログラミング入門」(技術評論社)を参考にしました。

環境 : VisualStudio 2012 / Windows 8

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace csfsStoreXaml02
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }
        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            var t = Module1.test3("ABC123-456,789");

            foreach (var v in t)
            {
                listBox1.Items.Add(v);
            }
        }
    }
}
module Module1
open System.Text.RegularExpressions

let re = Regex("[0-9]+")
let test3 x = 
    re.Matches(x) 
    |> Seq.cast<Match> 
    |> Seq.map(fun m -> m.Value) 
    |> Seq.toList

これが積極的に業務でも使えればいいのですが、まだ難しい状況が続くことと思います。それはあまり使われない言語を使うと保守性が悪くなるため、これを嫌う傾向は強いからです。これは十分理解できます。
最近Rubyですら使えないことがありました。データコンバートのツールを作るとき、開発時間でJavaの1/4くらい、コード量では約半分でしたが、Javaで作ることになりました。実際はプロトタイプはRubyでつくり、それをJavaに移植した後作りこみ、という形でやりましたが、基本仕様がすでに動いているということは、とても心強かったです。
F#もこのような使い方ができれば意義あることかもしれません。

ちなみに現在開発中のWindowsストアアプリとは、F#はまだまだということで、JavaScript+SVGのものと、C#+XAMLです。
しかし最近のMicrosoftの言語環境は、本当にマニアックすぎる!?