天天看點

Windows Phone マイクロフォン プリーズ

Windows Phone マイクロフォン プリーズ

あれ、MSCセッションのフォローは?…つー話はおいておいて、今度はマイクロフォンでマイ録音する方法を紹介します。・・・まぁいいじゃん。

マイクロフォンは、Microsoft.Xna.Framework.Audio 名前空間のMicrophoneクラスで操作します。名前空間から判るとおり、この機能はXNA Frameworkを使うので、プロジェクトの參照にMicrosoft.Xna.Frameworkコンポーネントを追加しておきます。

そして、適切な場所で名前空間のUsing宣言をしておきます。

using Microsoft.Xna.Framework.Audio;

Microphoneクラスのインスタンスは次のコードで取得できます。

var mic = Microphone.Default;

バイブレータのときも同じ形式でインスタンスを取得していましたね。デバイス系はこういう形式が多いです。クラスリファレンスでコンストラクタがないものは、この形式かな?と思ってみるとよいでしょう。

マイクロフォンを使うプログラムの手順は、こんな感じ

  1. マイクロフォンインスタンス參照取得
  2. サンプリングレートを設定(BufferDurationプロパティ)
  3. マイクロフォンの音データをサンプリングする度に呼ばれるハンドラを登録(BufferReadyイベント)
  4. サンプリングした音データを都度、そして、順次保持していくためのストリームを用意
  5. マイクロフォンの音サンプリングを開始(Startメソッド)
  6. 登録したハンドラがコールされるたびに、マイクロフォンから音データを取り出し(GetDataメソッド)、用意したストリームに書き込む
  7. マイクロフォンのサンプリングを終了(Stopメソッド)
  8. 取り込んだ音データをファイル化

これをコードで書くと・・・

先ず、クラスのメンバー変數で以下を用意して、

private Microphone mic;

private MemoryStream stream;

private byte[] buffer;

どこか適當な起動場所(例えばボタンのクリックハンドラとかタップハンドラなど)に以下のコードを記述します。

// 1.~5.までのコード

mic = Microphone.Default;

mic.BufferDuration = TimeSpan.FromMilliseconds(100);

buffer = new byte[mic.GetSampleSizeInBytes(mic.BufferDuration)];

mic.BufferReady += new EventHandler<EventArgs>(mic_BufferReady);

stream = new MemoryStream();

mic.Start();

これで5番目までが完了。ここではサンプリングを100msecに設定しています。ハンドラの中で音データを取り出すために必要なバッファのサイズはここで確定でき、あとは再利用していくので、ここでnewして用意しています。ストリームはMemoryStreamを使います。

そして、ハンドラーは、

private void mic_BufferReady(object sender, EventArgs e)

{

    int size = mic.GetData(buffer);

    Deployment.Current.Dispatcher.BeginInvoke(()=>

    {

         stream.Write(buffer, 0, size);

    }

}

こんな感じ。用意したバッファにマイクから音データを取り出し、ストリームに書き込んでいます。6番目のステップね。ストリームに書き込むときは、BufferReadyのハンドラをコールするスレッドのオーナーとストリームのオーナーが違うので、Dispatcherへの委譲が必要。

で、例えば終了用のボタンを用意して、そのクリックハンドラで、

mic.Stop();

とやれば、サンプリングが終了します。

これでOK…とはいきません。殘念ながらこれではうまく動かないんですね。何故かというと、MicrophoneクラスはXNAフレームワークの機能で、サンプリングするには、XNAフレームワークの処理ループを回さないと、サンプリングしてくれないからなんです。そのために、先ず、名前空間參照として以下を追加します。

using System.Windows.Threading;

using Microsoft.Xna.Framework;

クラスのメンバー変數として、

private DispatcherTimer timer;

を加え、そして、1.~5.のコードの前に、

timer = new DispatcherTimer();

timer.Interval = TimeSpan.FromMilliSeconds(50);

timer.Tick = delegate { try { FrameworkDispatcher.Update() } catch { } };

timer.Start();

を加えます。これで、マイクのサンプリングを行う為の更新ループが動くことになります。これで、メモリストリームへの書き込みは完了です。あ、あと、micのStop()メソッドをコールしたら、timer.Stop()メソッドのコールも忘れずにやっておきましょう。

さて、このままだと、サンプリングしたプログラムの中だけでしかデータを使うことが出來ないので、最後にファイルに落とす方法を書いておきます。例えばこんな感じ。

string fileName = "...wav";           

var storage = IsolatedStorageFile.GetUserStoreForApplication();

if (storage.FileExists(fileName))

{

    storage.DeleteFile(fileName);

}

var fileStream = storage.CreateFile(fleName);

var recordedData=stream.ToArray();

fileStream.Write(recordedData, 0, recordedData.Length);

fileStream.Close();

fileStream.Dispose();

stream.Close();

stream.Dispose();

これでアイソレーテッドストレージ領域に音ファイルとして永続化されます。

ちゃんちゃん。

…って、え?再生したい?ならコードはこれで。

var storage = IsolatedStorageFile.GetUserStoreForApplication();

var fileStream = storage.OpenFile(fileName, FileMode.Open, FileAccess.Read);

byte[] playBuffer = new byte[fileStream.Length];

fileStream.Read(playBuffer, 0, playBuffer.Length);

SoundEffect effect = new SoundEffect(playBuffer, myMic.SampleRate, AudioChannels.Mono);

effect.Play();

轉載于:https://www.cnblogs.com/iphone6/archive/2011/11/22/2258926.html