フォトアルバム

他のアカウント

更新ブログ

Powered by Six Apart
Member since 03/2005

« 2011年1月 | メイン | 2011年3月 »

竹キーボード 日本語版 試作品完成

3q108

とりあえず、工場から写真が届きました。

しかし、ソコから日本までの発送ルートがまだ未確定でして・・・

その為、金額もまだ決定出来ておりません。

この日本語版キーボードは空輸になると思いますので、

金額は多少お高くなってしまうと思いますが、

出来る限りギリギリの線で提供できる様に努力致します。

ご期待下さい!!

何故こんなにテンションが高いかって???

いや、本日、誕生日だったりして^^;

もうおめでたくも無いお年頃ですが、

一応テンション上がってガタつきBlog を2件程UP してみました。

風邪ひいて咳が止まらない状況ですが、

この歳も頑張ってやってきますよ~

先進国、新興国と言う二つのモノサシって言うのは・・・

どうかと思いますが、

  

実は先進国らしからぬ日本~生産と物価に見る新興国との類似性

http://diamond.jp/articles/-/11246  

 

日本のデータがアジアの新興国と近いのは、

日本もアジアの一員だし欧米と比べてアジアの影響が大きいのは当然の事だと思うのですが・・・

では、どうしようと???

今の日本は欧米と比べる必要は無い。

アジアに世界が注目する市場が有り、そのアジアの端っこに日本が有る訳ですから。

どちらかと言うと、今までの日本は「欧米組」見たいな目線で、

「アジアの一員」と言う意識が少なかったのではないかと感じます。

しかし、最近は「アジア」が強くなってきたので、

日本人のアジアの一員と言う意識も高まって来たのかなと思います。

ソレで良いじゃないですか!!

コレで行きましょう!!

過去の件でアジア各国から嫌われ者だった日本ですが(今もか???)、

皆で頑張って行きましょうよ~

アジアが盛り上がれば日本も上がるから。

頑張るぞ~

日本は大国でも小国でも無い、中国だったりして^^;

この記事
 
大国を目指すか、小国として生きるべきか。
今こそ確固たる“国家像”に基づいた日本外交を
http://diamond.jp/articles/-/11247
 
今の日本が大国を目指しているとは思えない。
ソレは、政治が外交がと言う問題では無い。
国民が大国を目指していないからである。
 
実は、日本国民は現状に満足しているのだと思う。
不平不満や批判的な意見は言うが、行動に移す訳ではない。
本当に何とかしなければならない場合は、
自分自身が行動するしかない。
しかし、今の状態は面白おかしく政治を批判したり、
唯、不平不満を言うだけで何の改善もしようとしない。
コレは政治の話では無く国民の話で・・・
 
日本は貧しい国では無い。
この世の中の状態でもちゃんと生活が出来る。
コレは、国としては大変素晴らしい事だと思う。
世界の中でもコレだけの水準の国は少ないと思う。
しかしそのおかげで、ハングリーさを失い、
自ら得るモノではなく与えられるモノに期待する様になってしまっている。
考え方が内向きな思考にあると思います。
もし、大国を目指すのであれば、コレでは成し得ない。
よりハングリーに、アグレッシブに、
我々自身が動いて海外に向けて活躍しない限り、大国日本は実現出来ない。
 
今、中国では若者の間で民主化運動が起きています。
コレは彼らが自国の将来に対して現状の変化を期待し、
自らが行動をしている良い見本だと思う。
もちろん、現在の中国の政治もソレを抑え込もうとするが、
起きた運動は事実であり、何れコレがきっかけとなり変化が起こる事になると思う。
その時に、民意が政治を動かす瞬間なんだなぁ~と感じるハズ。
 
我々日本人にはココまでの行動力は有るのか?
無い。
何故なら、そこまで大きな不満が無いから。
そこまでのエネルギーを起こす材料が無いからである。
唯、足を引っ張り合う政治を見たまま批判しているだけで、
真剣に現状を変えようと考えていない。
今のままでは大国にも、小国にもなれない。
もう一度、大国日本を目指すのであれば、
我々国民が全員日本代表として戦うべきであると思います。
 
 
※中国からのBlog 書き込みの為、使用出来ない言葉が有るので表現が難しく
 読みにくい文章になってしまいました。
 一回目に書いた文章は蹴られちゃったし^^;

続DTMF 解析

また例の奴を書き続けていたのですが・・・

今度はもう少し数値的にDTMF を解析するように変更しました。

ソレと、各種オーディオフォーマットに対応しました。

 

まず、チャンネル数が1 の場合はモノラルで、2 の場合はステレオです。

そして、ビットレートが8Bit か16Bit かを選択が出来ます。

その為、データ格納変数を4種類用意ました。

    Private _AudioIn_M8_ReadData() As Byte
    Private _AudioIn_M16_ReadData() As Int16
    Private _AudioIn_S8_ReadData() As Int16
    Private _AudioIn_S16_ReadData() As Int32

コレは、そのままM8 がモノラル8Bit で、S16 はステレオ16 Bit と言う意味ですが・・・

モノラルの8Bit はByte で、16Bit はInt16 でそのままの配列ですね。

ステレオの場合、1 データに対して、左チャンネル、右チャンネルとデータが書かれますので、

8Bit の場合、左と右用で16Bit を用意します。

16Bit の場合は、同じ事で32Bit ですね。

ちなみに、1つの配列の要素に、左右でデータ上位下位に分かれています。

Byte ストリーミングは左右左右左右とデータが流れるので、

配列要素には、下位8Bit(16Bit) 左音声、上位8Bit(16Bit) 右音声となっております。

実際のデータは、8Bit データの場合 0 ~ 255 の値で、128 が無音(0) として扱われます。

16Bit データの場合 -32768 ~ 32767 で、0 が無音として扱われます。

コレを、FFT 用のバッファに移して音声データを周波数変換します。

 

        If _WAVFMTEX.nChannels = 1 And _WAVFMTEX.wBitsPerSample = 8 Then
            'Monaural 8 Bit
            For i = 0 To AudioInBufferNum - 1
                _AudioIn_M_FftData(i) = (CType(_AudioIn_M8_ReadData(i), Double) - 128.0)
            Next
            Four1(_AudioIn_M_FftData, FFT_FORWARD)
        ElseIf _WAVFMTEX.nChannels = 1 And _WAVFMTEX.wBitsPerSample = 16 Then
            'Monaural 16 Bit
            For i = 0 To AudioInBufferNum - 1
                _AudioIn_M_FftData(i) = CType(_AudioIn_M16_ReadData(i), Double)
            Next
            Four1(_AudioIn_M_FftData, FFT_FORWARD)
        ElseIf _WAVFMTEX.nChannels = 2 And _WAVFMTEX.wBitsPerSample = 8 Then
            'Stereo 8 Bit
            For i = 0 To AudioInBufferNum - 1
                Dim R_HiBit As Integer = _AudioIn_S8_ReadData(i) And &HFF
                Dim L_LowBit As Integer = (_AudioIn_S8_ReadData(i) >> 8) And &HFF
                _AudioIn_R_FftData(i) = (CType(R_HiBit, Double) - 128.0)
                _AudioIn_L_FftData(i) = (CType(L_LowBit, Double) - 128.0)
            Next
            Four1(_AudioIn_R_FftData, FFT_FORWARD)
            Four1(_AudioIn_L_FftData, FFT_FORWARD)
        ElseIf _WAVFMTEX.nChannels = 2 And _WAVFMTEX.wBitsPerSample = 16 Then
            'Stereo 16 Bit
            For i = 0 To AudioInBufferNum - 1
                Dim R_HiBit As Integer = _AudioIn_S16_ReadData(i) And &HFFFF
                Dim L_LowBit As Integer = (_AudioIn_S16_ReadData(i) >> 16) And &HFFFF
                _AudioIn_R_FftData(i) = CType(R_HiBit, Double)
                _AudioIn_L_FftData(i) = CType(L_LowBit, Double)
            Next
            Four1(_AudioIn_R_FftData, FFT_FORWARD)
            Four1(_AudioIn_L_FftData, FFT_FORWARD)
        Else
            Return False
        End If

 

基本的に、普通のwaveIn 関係の処理に、上記の様な処理を追加すれば複数フォーマットに対応できると思われます。

 

さて、サンプリングレートがメンドクサイのですが・・・

入力デバイスのサンプリングレートによって、周波数分解能が変わります。

私のPC では、下記三種類のサンプリングレートが選択できます。

 11.025 kHz

 22.050 kHz

 44.100 kHz

計算上では、この半分の数値が再生周波数になると思うのですが、

※本来はフィルタが有る為、上下20Hz 程切られてると思うが・・・

11.025 kHz の場合、一秒間に11025 データです。

コレに対し、waveIn で取得するデータ数は下記で定義してあります。

    Private Const AudioInBufferNum As Integer = 1024

1024 個のデータをFFT にかけると、実数部512 、虚数部512 個のデータが出来上がります。

512 個のデータの内、半分が対象のデータとなるので、256 個のデータが周波数成分になります。

1024 / 256 = 4 ですので、周波数レンジは、11025 / 4 = 2756.25 ≒ 2.8 kHz

2800 / 256 = 10.93 Hz の分解能と言う事になります。

DTMF の各周波数に合わせて、データ分解能を計算します。

    Private Const Hz697 As Integer = 697
    Private Const Hz770 As Integer = 770
    Private Const Hz852 As Integer = 852
    Private Const Hz941 As Integer = 941

    Private Const Hz1209 As Integer = 1209
    Private Const Hz1336 As Integer = 1336
    Private Const Hz1477 As Integer = 1477

    Private _HiHz As Integer
    Private _LowHz As Integer
    Private _WaveDataRange As Double

    Private _Hz697Column As Integer
    Private _Hz770Column As Integer
    Private _Hz852Column As Integer
    Private _Hz941Column As Integer

    Private _Hz1209Column As Integer
    Private _Hz1336Column As Integer
    Private _Hz1477Column As Integer

        _WaveDataNum = AudioInBufferNum / 4
        _HiHz = _WAVFMTEX.nSamplesPerSec / 4
        _LowHz = 0
        _WaveDataRange = _WaveDataNum / (_HiHz - _LowHz)

        _Hz697Column = Hz697 * _WaveDataRange
        _Hz770Column = Hz770 * _WaveDataRange
        _Hz852Column = Hz852 * _WaveDataRange
        _Hz941Column = Hz941 * _WaveDataRange

        _Hz1209Column = Hz1209 * _WaveDataRange
        _Hz1336Column = Hz1336 * _WaveDataRange
        _Hz1477Column = Hz1477 * _WaveDataRange
 

コレで、FFT 後、値を周波数変換したデータ配列(この場合は256 個の配列)内の、

何処の値がDTMF のどの周波数かが解る。

んで、その値を使って下記の様に配列からデータを取り込む。

※この場合は、ターゲットの上下1個ずつ、計3個のデータを取って、その平均値を使って解析している。

        Dim Hz697 As Double = (_WaveDataM(_Hz697Column - 1) + _WaveDataM(_Hz697Column) + _WaveDataM(_Hz697Column + 1)) / 3.0
        Dim Hz770 As Double = (_WaveDataM(_Hz770Column - 1) + _WaveDataM(_Hz770Column) + _WaveDataM(_Hz770Column + 1)) / 3.0
        Dim Hz852 As Double = (_WaveDataM(_Hz852Column - 1) + _WaveDataM(_Hz852Column) + _WaveDataM(_Hz852Column + 1)) / 3.0
        Dim Hz941 As Double = (_WaveDataM(_Hz941Column - 1) + _WaveDataM(_Hz941Column) + _WaveDataM(_Hz941Column + 1)) / 3.0
        Dim Hz1209 As Double = (_WaveDataM(_Hz1209Column - 1) + _WaveDataM(_Hz1209Column) + _WaveDataM(_Hz1209Column + 1)) / 3.0
        Dim Hz1336 As Double = (_WaveDataM(_Hz1336Column - 1) + _WaveDataM(_Hz1336Column) + _WaveDataM(_Hz1336Column + 1)) / 3.0
        Dim Hz1477 As Double = (_WaveDataM(_Hz1477Column - 1) + _WaveDataM(_Hz1477Column) + _WaveDataM(_Hz1477Column + 1)) / 3.0

後は、それぞれの周波数の数値が、基準より上かどうかを判断し、DTMF が入力されたか判断している。

※この場合は、全周波数の平均値を取り、その値に倍率をかけたモノを閾値としている。

 図の中の赤線がその値。

        If Hz697 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz697Flag = True
        End If
        If Hz770 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz770Flag = True
        End If
        If Hz852 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz852Flag = True
        End If
        If Hz941 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz941Flag = True
        End If
        If Hz1209 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz1209Flag = True
        End If
        If Hz1336 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz1336Flag = True
        End If
        If Hz1477 > _WaveDataM_AveVal * JudgeAveAmp Then
            Hz1477Flag = True
        End If

        _Flag_1 = Hz697Flag And Hz1209Flag
        _Flag_2 = Hz697Flag And Hz1336Flag
        _Flag_3 = Hz697Flag And Hz1477Flag
        _Flag_4 = Hz770Flag And Hz1209Flag
        _Flag_5 = Hz770Flag And Hz1336Flag
        _Flag_6 = Hz770Flag And Hz1477Flag
        _Flag_7 = Hz852Flag And Hz1209Flag
        _Flag_8 = Hz852Flag And Hz1336Flag
        _Flag_9 = Hz852Flag And Hz1477Flag
        _Flag_KM = Hz941Flag And Hz1209Flag
        _Flag_0 = Hz941Flag And Hz1336Flag
        _Flag_SP = Hz941Flag And Hz1477Flag

 

ソース内の特定部位しか書いて無いので意味不明な記事ですが・・・

後は適当にグラフはPictureBox に

        Dim BMPImage As Bitmap
        Dim WaveGraphics As Graphics
        BMPImage = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        WaveGraphics = Graphics.FromImage(BMPImage)

        For i = 0 To _WaveDataNum - 1
            Dim XScl As Integer = (PictureBox1.Width / _WaveDataNum) * i
            Dim YLen As Integer = (PictureBox1.Height / _WaveDataM_MaxVal) * _WaveDataM(i)
            If YLen > PictureBox1.Height Then
                YLen = PictureBox1.Height
            End If
            WaveGraphics.DrawLine(Pens.Blue, XScl, PictureBox1.Height - 10, XScl, PictureBox1.Height - YLen - 10)
        Next
        Dim AveLen As Integer = (PictureBox1.Height / _WaveDataM_MaxVal) * (_WaveDataM_AveVal * JudgeAveAmp)
        WaveGraphics.DrawLine(Pens.Red, 0, PictureBox1.Height - AveLen - 10, PictureBox1.Width, PictureBox1.Height - AveLen - 10)

こんな事して絵を描いているだけですね^^;

ちなみに、縦線は、それぞれDTMF の周波数を緑と紫で線をひいています。

サンプリングレートを上げる場合は、もちろん周波数分解能が低くなるので、

取得データ数を増やす必要が有ります。

処理速度を考えると、やはり11.025 kHz が安定してDTMF 検出出来る感じです。

 

結局、このプログラムで週末を完全に潰してしまった^^;

なんだかなぁ~

この部分だけソース公開するか、全部合わせてフリーソフトにするかはまた検討します。

※なにがしAPI の関係でこのソフトをどうするか検討中です^^;

 

さて、寝るぞぉ~

Scskpbx2

ようやくDTMF 解析が可能に!!

ははは~

趣味プログラムで作っていた奴、

とあるAPI から音声を取り出して、その音声にDTMF が含まれてるか確認する奴。

Scskpbx

「とあるAPI」が何なのか判明出来る画像デスが^^;

とりあえずデバッグで、マイク入力からDTMF が解析出来ました。

※この画像では「5」を判別しました

実は、とあるAPI はP2P の接続時のみAPI 標準のメソッドでDTMF が読めるのですが、

「なにがしIn」 のサービスを使っての接続時には標準のメソッドではDTMF が読めません。

その為、音声を解析してDTMF を判別しなければなりません。

コレは、まさにそのプログラム。

waveIn を利用し、オーディオデバイスから音声データを取得。

そのデータをFFT で周波数分析し、特定の周波数成分でDTMF を判断する。

さて!!

勘の良い方はもう既に何のためにコレを作っているかお分かり頂けると思うのですが^^;

このプログラムは、既にP2P 接続では下記の様な動作を行っております。

 

1.クライアント1が、マスタークライアント(等ソフトと「なにがし」が起動しているマシン)に接続する。

2.等ソフトがなにがしAPI 経由でクライアント1の接続に応答

3.クライアント1がDTMF で電話番号の様なモノを打ち込む

4.マスタークライアントが、クライアント1から入力されたDTMF の番号に何かを転送接続する

5.クライアント1と転送接続が確立される

6.クライアント1は転送接続先と何かが出来る(コミュニケーション的な・・・)

 

ココまで出来ているので、後は、P2P 接続で無い場合、自作DTMF 解析を使って同じ事をすれば・・・

上記「クライアント1」の部分が、なにがしIn の接続に変わって・・・

と、言う事が可能になる訳です。

このソフト名が「SCSKPBX」って言うんで、まさにソレですが(笑)

コレ、厳密に言うと違法らしいですね^^;

個人で楽しむ分には許してもらえないかしら~

 

ま、今回一番の努力ポイントは、waveIn の部分かな・・・

なんせVB.NET の資料が少なくて^^;

しかし、コレのおかげで、以前から作りたかった

SCPTH(ただ、マイクの音を拾ってスピーカーに垂れ流す)が作成可能になった。

コレは、イヤホンで音楽聞いてる時に、周りの音が聞こえなくなるから、

ソコにPC のマイクから音を拾ってタレ流しておけば良いかなぁ~と言う発想^^;

 

週末につまらんソフトを作ってたらこんな時間に・・・

さみしい生活だなぁ^^;

さて、もうひと頑張りしちゃおうかな!!

コラ~!! 誰だ~!! バトコンラーメンにこんなイタズラする奴は!!

Img_0988

とりあえず、ソコに居た人達全員に、好きな数字を言ってもらい・・・

合計の数だけラー油をスプーンですくって投入した結果がコレ(笑)

 

http://s14.dcnblog.jp/pri/2011/02/post-4e09.html

※この時の奴は、ノーマルのバトコンラーメンの写真

 

最終的には、そのテーブルのラー油ポットを全部使っちゃったんですが・・・

味は、意外と辛いです(笑)

小一時間は胃の中が燃えています。

今回も、被害者はOSM 君^^;

私が帰国した際には、皆さん胃薬を用意して待ってて下さいね!!

まるで、ぐいそば界のオーケストラや~

既にハーモニーでは無い・・・

 

まずはベースのぐいそばを注文

Img_0973

月見とろろそばですな・・・

 

コレに!!

Img_0972

トッピングを追加注文

上から、とろろ昆布、コロッケ、天ぷら、山菜、おろし、揚げもち、から揚げ

※月見ととろろはベースで、ねぎ特盛りはトッピングから除外(既に乗ってるため)

 

そうすると、こうなります。

ハイ~、ドブンと!!

Img_0976

角度を変えて~

よっこらしょっと!!

Img_0977

おまけ!!

Img_0978

ま、そう言う事で・・・

とにかく、ぬるい!!

月見とろろの時点でぬるいのに、さらに山菜、おろしでまた温度を下げてしまう。

この点はぜひ改良して頂きたい!!

味に関しては、もはや「あっさりこってり味」としか表現出来ない・・・

でも不味くは無い^^;

ベース490円、トッピング合計570円 合計1060円

商品名称「月見とろろとろろ昆布山菜おろしコロッケ天ぷらから揚げ揚げもちそば」

まぁ、同じ金額で安いステーキを喰うよりボリュームが有りますよ。

意外とアホ度が低いと言う事も判明いたしました。

次の遊びを考えよう・・・

 

ごちそうさまでした。

Img_0979

塩尻駅の楽しみ

塩尻駅の楽しみ
立ち食いそば!
略してぐいそば・・・
この寒い季節、待合室で食べるぐいそばは格別やぁ〜

久々の社食

久々の社食
明日からまた中国行きなんで・・・
今日は電気屋仕事です!
たまには良いですね〜
腹ペコにカレーを流し込む!!