ちょっと油断していたたら、音声認識対応言語が9言語ぐらい増えてた。
英語(ガーナ)
英語(ケニア)
英語(タンザニア)
フィリピン語
フランス語(スイス)
ドイツ語(オーストリア)
インドネシア語
ベトナム語
マレーシア語
www.microsoft.com
Microsoft Translatorアプリでも実現でしていましたが、よりリアルタイム性が高い感じで翻訳ができるMicrosoft Group Transcribeアプリが登場してきました。まずはiOSアプリから。
デバイスのマイクを使ってその場で音声を取得するので「スマホは発話者のそばで!」みたいな使い方Tipsが書かれていますね。
回線経由の音声じゃない分、音声認識率はよさそうですね。
同じ部屋の中にいる人通しではアプリを立ち上げるとbluetoothでみつけてワンタップで参加できます。
あとは5桁のコード、もしくは、QRコードでも同じ会議室にさんかできるので、遠く離れた人同士は5桁のコードで参加ですね。
5桁のコードが判ってしまうと世界中の誰でも参加できるし、近くにいる人とはbluetoothでサクッと参加できますね。
とにかく不特定多数の人との会話の文字起こしには便利ですね。
一方、企業内の会話とかに外に漏れたくない場合なんかはちょっとダメそうですね。適材適所というところでしょうか。
日本語端末で話をすると、自分の発話の日本語のみが表示されます
↓
英語端末に届くと日本語がでて、その下に英語で翻訳されます。
↓
英語端末で英語を話すと、自分の発話の英語のみが表示されます。
↓
日本語端末に届くと英語が出て、その下に日本語で翻訳されます。
同時に話すと誰か1人の端末の音声認識だけがONになるようです。
つまり複数人が同時にどんどん喋ったとしても、少しでも早く話し始めた人以外は認識がONにならないようです。
でも、ちょっとでも息継ぎで間を開けると認識していた端末以外の音声をその瞬間だけ取得するような動きです。
「ちょっとまって」とか入れずらいので、話す側が少し工夫したりするといいんじゃないでしょうか。
会議中の発言(つまり表示されていた状態)は、いつでも履歴から参照できます。
そこから共有もできますね。
端末ごとに履歴の内容が違う(言語ごとに、他国語から自国語への翻訳表示部分が違う)ので端末に保存されているのかな。
話し始めて、最初の文字がでてくるまで若干待たされる感じはしますが、そこからは比較的スムーズです。
類似の無料アプリがいろいろありましたが、そのあたりを使っている場合は、これで充分かな。
Ignite 2021が始まりましたね。
開発者していると分かるのですが自社イベントに合わせて自プロダクトの新機能の提供を開始するとかはよくある話です。
ギリギリスケジュールでとりあえず形だけってケースも多いと思うけれど、Microsoftさんの場合は、Private Preview→Public Preview→GAみたいなマイルストーンで確実に提供する感じなのでイベント合わせのリリースもすごくきっちりしていますね。
今回もたくさんのUpdateがありましたが、その中から注目している分野に絞ってご紹介します。
.NETラボ 勉強会 2020年11月 - connpass
.NETラボ 勉強会 2020年10月 - connpass
.NETラボでも何回か登壇させてもらったネタであるACSことAzure Communication ServicesのUpdateをご紹介します。
azure.microsoft.com
ACSの裏側はTeamsと同じアークテクチャーであることは公言されていましたし、ACSでビデオ会議を作るとそのURLはTeamsのそれと非常に似た構造ですし、繋がるようになるよとは書かれていたのですが、いよいよPublic Previewとなって誰でも試せるようになりました。
何がうれしいかといえば、自分のアプリからTeamsにつながることですね(そのままですね)。
Windowsだったら「自分のアプリとTeamsアプリ」みたいな感じで2つアプリを立ち上げればいいのであまり嬉しさは感じられないかもですね。
でも、スマホだったらどうでしょうか。2つアプリ同時起動して使うのはなかなか面倒ですし、自アプリとTeamsの両方で音声を使おうとするとTeams側に全部マイクを持ってかれちゃうなんてこともあります。
そこで登場するのが、ACSを組み入れて自分のアプリの中でTeams会議への参加部分も完結しちゃうアプローチですね。
docs.microsoft.com
ACSのビデオ会議に接続するAPIで接続先をTeams会議に合わせて次のように指定する感じですね。
const locator = {
threadId: [thread id],
organizerId: [organizer id],
tenantId: [tenant id],
messageId: [message id]
}
Teams会議の会議URLの構造は次のようになっているので、そこから抜き出して設定ですね。
http://teams.microsoft.com/l/meetup-join/[thread id]/[message id]?context={"Tid":"[tenant id]","Oid":"[organizer id]"}
azure.microsoft.com
現実空間とデジタル空間のオブジェクトの位置合わせをAzure上で行うAzure Object AnchorsがPublic Previewになりましたね。
いままでは限られた範囲での公開でイベントで事例などがあっても自分たちで試せませんでしたが、これで誰でも試せます!
azure.microsoft.com
3DモデルのレンダリングをAzure側で行って、結果を受信できるAzure Remote RenderingがGAとなりました。
ポリゴン数が多いような場合でもAzureパワーでなんとかなってしまいます。
東日本でも使えるので、より低レイテンシーな使い方ができるようになりましたね。
techcommunity.microsoft.com
マルチデバイスでリアルとバーチャルを融合するMicrosoft Meshが突然Previewしてきました。
詳細はまだよく調べていませんが、HoloLens 2アプリとAltspaceVRアプリがすでに提供されていて、その間でいろいろ共有できるみたいです。
Speech ServicesとかTranslatorとかは特にUpdateないみたいです。
それではDay2も眠いけど楽しみですね。
Day1も日本の昼間にリピートセッションあるので、ぜひ!
2021年8月からは、Google Playに新しくアプリを登録するには、従来のapkではなくAndroid App Bundle(aab)で登録することが必要になります。
Visual Studio + XamarinでAndroid向けアプリを作成するときも、もちろん、apkだけではなくaabで作成できます。
初期のころはaab作成がVisual Studioからはできず、MSBuildを使ってコマンドラインでaabファイルをつくらなければなりませんでしたが、最近のVisual Studioではアーカイブでも可能です。
aabを作成するには、Androidアプリのプロジェクトのプロパティを表示して、Androidオプション画面で設定します。
aab作成には本当に時間がかかるので、Release構成のみの設定が推奨されています。
そのため、[構成]を「Release」にしてから設定を変更します。
設定は簡単で、Androidパッケージ形式を「バンドル」にするとaab作成となります。このとき次の2つのチェックボックスが、値固定でグレーアウトします。
aapt2(Android Asset Packaging Tool)は、アプリのリソースをコンパイル、パッケージ化するために使用するビルドツールです。AAPT2 はリソースを解析してインデックスに登録し、Android プラットフォーム向けに最適化されたバイナリ形式にコンパイルします。
2つの設定が固定化されるのであれば、Debug構成でも同じ設定にしておいてデバッグしておくことが安全です。
aapt2については新規プロジェクト作成時はデフォルトONになっていますが、以前から使っているプロジェクトではOFFになっているものも多いでしょう。
それでは、[構成]を「Debug」にしてaapt2をONに設定しましょう。
Visual Studioが至れり尽くせりだなーと思うのは、Release構成側で「バンドル」を指定すると、Debug構成側も自動的に2つのチェックボックスが同じ値でグレーアウトしていました。
もちろん、パッケージ形式は「apk」のままです。
構成ごとの設定がおわったら、Release構成をアクティブにしてアーカイブします。
アーカイブが成功すると、アーカイブマネージャーにバンドル形式「aab」のエントリが表示されます。
アーカイブができたら、[配布]ボタンをクリックして「アドホック」でファイル作成して手動でGoogle Play Consoleにアップロードするか、「Google Play」でアップロードまで行うかを選んで、署名付きaabを作成します。
実機にインストールするためには、「アドホック」を選択して署名付きaabファイルを作成しましょう。
署名付きaabを実機にインストールしたいときは、adbコマンドを使って実行します。
Visual Studioのメニューからコマンドラインを起動して、USBに実機を接続してUSBデバッグを許可したらadb installします。
Successが出たら終了です。
実機で動作を確認してみましょう。
実機確認できたら、署名付きaabをGoogle Playに登録してみましょう。
試しに、登録済のapkと同じバージョンとバージョンコードで作成して登録してみると次のようなエラーとなりました。
当然ですが、apkとaabで同じバージョンをアップロードはできないようですね。
ついでといっては何ですが、配布するならば「Google Playで署名されています」マークを付けておきたいですよね。
新規に登録するときは自動的にGoogle Play Consoleで次のような表示になります。
既存登録済でこの表示がない場合は、手動で設定しないといけないのですが、次のQuitaが分かりやすかったです。
qiita.com
qiita.com
上から順番に読んでみると理解しやすくお勧めです。
それではVisual StudioでのAndroidアプリ開発、楽しんでいきましょう!
以下、NAudio v1.10での確認となります。
NAudioですが、音声入出力に非常に便利なライブラリで、.NET Framework以外にも様々なプラットフォームで動作します。
github.com
しかし、UWPで使用する場合、いつくかの注意点があります。
それは、ARM / ARM64に限らずx86をプラットフォームターゲットとしたときも.NETネイティブコンパイル時には次のような実行時エラーが発生します。
System.ArgumentException: 'Unsupported Wave Format'
この実行時エラーは、NAudioのサンプルコードでNAudioUniversalDemoがあるので、そちらで確認することができます。
このサンプルコードを.NETネイティブコンパイルして実行して「Record」ボタンをクリックすると、NAudioの中、具体的には、NAudio.Wave.WasapiCaptureRT.InitializeCaptureDeviceの中で下記のエラーが発生します。
こちらは録音デバイスがサポートしていないWaveフォーマットを指定したからだということです。
こちら、.NETネイティブではないときには、WaveFormatとしてサンプリングレート48000、32ビット、1チャンネルのIeeeFloatなフォーマットが自動的に指定されますが、.NETネイティブコンパイル時はその自動指定が行われず、ソースコードを読む限りはAudioClient.csの中のpublic WaveFormat MixFormatプロパティのGetの中でaudioClientInterface.GetMixFormatのところで取得ができていないようです。
注:Visual Studio 2019を使用し、ターゲットバージョン=2004 (ビルド19041)、最小=1803(ビルド17134)を指定
それでは、.NETネイティブコンパイルしなければいいのでは?となりますが、ストアに登録して配布するときは.NETネイティブコンパイル必須となっているので、配布手段はどうあれ.NETネイティブコンパイルで動作しないというのは、今後を考えると避けたいところです。
対応策としては、サンプルコードNAudioUniversalDemoでいえばMainPageViewModel.csのなかでrecorder.StartRecording()を実行する前に、明示的にWaveFormatを指定してしまうことです。
NAudio/MainPageViewModel.cs at master · naudio/NAudio · GitHub
recorder.WaveFormat = new WaveFormat(48000, 32, 1);
なお、この場合、IeeeFloatではなくPCMのサンプリングレート48000、32ビット、1チャンネルとなります。
また、万が一、指定したサンプリングレートおよびチャンネル数が、該当のデバイスでサポートしていない録音デバイスだったときも実行時エラーとなります。
こうなってくるとストアに登録して広く公開するのはなかなか難しい状況だといえるでしょう。
例えば、ARM64 Windows機のLenovo C630のInternal Microphoneは、サンプリングレート48000Hz、16ビット、1チャンネルですが、インテルなWindows機だと2チャンネルの場合があります。
NAudioのMixFormat取得ロジックは.NETネイティブコンパイルしていないときと、.NETネイティブコンパイルしたときではどのように違うか確認してみましょう。
NAudioのGitHubからソースコードを取得して、AudioClient.csのMixFormatクラスにブレイクポイントを貼って、デバッグ実行をしてみます。
48000Hz、16bit、2チャンネルの録音デバイスが
非ネイティブのときは、MixFormatの戻り値は、サンプリングレート48000Hz、32bit PCM、2チャンネルとなります。
{32 bit PCM: 48kHz 2 channels wBitsPerSample:32 dwChannelMask:3 subFormat:00000003-0000-0010-8000-00aa00389b71 extraSize:22}
AverageBytesPerSecond: 384000
BitsPerSample: 32
BlockAlign: 8
Channels: 2
Encoding: Extensible
ExtraSize: 22
SampleRate: 48000
SubFormat: {00000003-0000-0010-8000-00aa00389b71}
averageBytesPerSecond: 384000
bitsPerSample: 32
blockAlign: 8
channels: 2
dwChannelMask: 3
extraSize: 22
sampleRate: 48000
subFormat: {00000003-0000-0010-8000-00aa00389b71}
wValidBitsPerSample: 32
waveFormatTag: Extensible
この中のsubFormatの値がWAVE_FORMAT_IEEE_FLOATを意味しています。
この内部値は外から見えないので、外から見えるrecorder.WaveFormatの値を見てみましょう。
こちらは、IeeeFloatとして取り出せます。
{IeeeFloat}
WaveFormat未指定時に本来期待されている動きは、この動きになります。
それでは.NETネイティブコンパイルしたときの値をみてみましょう。
MixFormatの戻り値は、サンプリングレート48000Hz、32bit PCM、2チャンネルとなりますが、クラスの型値がExtensibleのままでPCM表記になりません。
{NAudio.Wave.WaveFormatExtensible}
AverageBytesPerSecond: 384000
BitsPerSample: 32
BlockAlign: 8
Channels: 2
Encoding: Extensible
ExtraSize: 22
SampleRate: 48000
SubFormat: {System.Guid}
averageBytesPerSecond: 384000
bitsPerSample: 32
blockAlign: 8
channels: 2
dwChannelMask: 3
extraSize: 22
sampleRate: 48000
subFormat: {System.Guid}
wValidBitsPerSample: 32
waveFormatTag: Extensible
値を確認すると今回の原因はSubFormatにWAVE_FORMAT_IEEE_FLOATを意味する値が入っていないことがわかりました。
しかしここで注目すべきは、サンプリングレート、ビット数、チャンネル数などは取得ができてる点です。もしこれらの値を取得できれば、new WaveFormat(48000,32,1)のように指定してNAudioに該当録音デバイスのフォーマットが指定できることになります。
NAudioの内部状態のところでエラー判定されているので、NAudioの外側からどうにかできる問題じゃなさそうです。
そうなってくるとNAudioのどのクラスで対応するかですが、UWPのみの問題だと考えると、WasapiCaptureRTクラスの中で対応するのがよさそうです。
audioClient.MixFormatメソッドの戻り値を変数名mixにいれて、それがWaveFormatExtensibleであればビット数に応じてIeeeFloatかPCMか明示してフォーマットを作成することにします。
例えば、先ほどの48000Hz、16bit、2チャンネルの録音デバイスであれば、内部変数のwaveFormatは下記のようにIeeeFloatとして処理される内容になります。
{NAudio.Wave.WaveFormat}
AverageBytesPerSecond: 192000
BitsPerSample: 32
BlockAlign: 4
Channels: 1
Encoding: IeeeFloat
ExtraSize: 0
SampleRate: 48000
averageBytesPerSecond: 192000
bitsPerSample: 32
blockAlign: 4
channels: 1
extraSize: 0
sampleRate: 48000
waveFormatTag: IeeeFloat
このオリジナルのNAudio.dllは、Releaseビルドすれば、NAudio\bin\Release\uap10.0フォルダに出力されます。
自分のUWPプロジェクトでnugetではなくからそのDLLを参照するように切り替えれば、.NETネイティブコンパイルしたUWPアプリも正常にNAudioが動作します。
どうせならばと、この件は本家にプルリクしてみました。
[en]
When I try to create a web app in Azure and try to specify the runtime stack, I get the following message.
I think ”.NET 5" should be on the ".NET Core" side, but what do you think?
[jp]
AzureでWebアプリを作成しようとしてランタイムスタックを指定しようとすると以下のような表示になります。
「.NET 5」は、「.NET Core」側にあった方がよいと思うのですが、どうでしょうか。
2DなUWPアプリで一覧表示したボタンをクリックすると、FilePickerでファイルを指定してその行に画像を表示したいという質問を頂いたので、まとめます。
なお、少々手抜きをしていて、Modelの中でFilePicker起動しちゃってます。
本来であれば、イベントあたりを使って、ModelじゃなくてViewとかに通知を伝搬して、そこでFilePickerを呼び出して、ファイルから画像設定のModelをView→ViewModel→Viewという感じに読んであげるのがいいような気がします。
gist.github.com
ボタン押した行をイベントとして外に通知して、外側のImageModelクラスでImageSourceを設定した感じに変えた方がいいと思います。
※後日変えると思います