>先ほどサンプリングレートを下げる事も試したのですが、
サンプリングレートを調節する部分は2か所あります。
#include "hspwave.as"
#define threshold 1000 //これより大きければ検出
#define fs 8000 //0から4kHzまでの信号をサンプリング
#define intervalms 5.0 //調べる間隔[ms]
#define bufferms 100.0 //バッファ[ms]
#define byte 2 //量子化サイズ(16bits)
//時間をポイントに変更
buffersize = int(bufferms/(1000f/fs))*byte
//調べる間隔
intervalpoint = int(intervalms/(1000f/fs))
//調べる回数
loopa = buffersize / (intervalpoint*byte)
w_in_open fs,byte * 8,1 //初期化 ←サンプリングレート調節【1】
sdim buf,buffersize * 10
w_in_add buf,buffersize,1
repeat
repeat
w_in_bufs state:if state==0 :break
await 0
loop
number = 0
repeat loopa
c = wpeek(buf,number)
if c & 0x8000: c -= 0x10000
if abs(c)>threshold:count++
number += intervalpoint * byte ←サンプリングレート調節【2】
loop
w_in_add buf,buffersize,0
gosub *calc
loop
*calc
color 255,255,255:boxf 0,0,300,300:color:pos 0,0
mes "振幅"+c+"\nカウント="+count
return
1か所目は、hspwaveの渡す命令の部分で、
ここでは、音の取り込む周波数帯域によって制限があります。
youtubeの例だと、基本周波数(音の周期)は3300Hzなので、
サンプリング周波数は6600Hzまで下げることが出来ます。
ここで指定すると、
サンプリング周波数÷2 Hz以上の音はローパスフィルタでカットされます。
ですので、下げすぎると多分音を認識できなくなるので注意。
2か所目は、自前でサンプリング周波数を変更している部分です。
こちらは、ローパスフィルタをかけていないので、
ここでのサンプリング周波数 ÷ 2Hz以上の音は折り返し歪となります。
折り返し歪は、前の書き込みの通りで、
折り返しがうまい具合に調節されていれば、問題ありません。
それで、例えば1か所目を最大限の6600Hzに設定(今回変更を加えた)とすると、
これはhspwaveの機能の部分なので、
w_in_add,w_in_bufs などのhspwaveの関数部分が
以前より高速化に動作すると考えられますが、
この部分はhspwaveの機能なので、速度的にはあまり変化は見られないと思います。
また 2か所目は、
intervalpoint = int(intervalms/(1000f/fs))
loopa = buffersize / (intervalpoint*byte)
によって計算されているので、
HSPのコード上の計算回数は相殺されるはずです。
というわけで、
サンプリング周波数は前回のソースコード以上いじれる部分は
そんなにないと思いました。
ただ、前回のソースコードは40サンプル飛ばしをしているので、
単純に考えると元のコードよりは、40倍速くなっているはずです。
これで重いとなると別の原因があるのかなって思います。
c = wpeek(buf,number)
if c & 0x8000: c -= 0x10000
if abs(c)>threshold:count++
値の精度が256通り(-128から127)だと、調節がしにくいかなと思い
65536通り(-32768から32767)つまり
量子化ビット数を8ビットから16ビットに増やしました。
ですので、値を16ビット符号付き整数型で抜き出している部分です。
if c & 0x8000 は、 if (c & 0x8000) != 0 の略です。すみません。
これは、符号付き整数型の場合は、負の数は2の補数表現で表します。
ググってみると分かると思います。
それで、16ビット目が1であるかどうかを調べています。
それで負の数なら32ビット符号付き整数型(HSPのint)に調節しています。
最初に新山葵さんが示したサンプルコードのように
量子化ビット数8ビットの方が速度は速くなると思います。
>一方で、Atomのマシンだと7000/8000以下で100ms以上の空白時間が発生するようです。
>5800/6600程度しか処理出来ず、やはり100ms程度
両方とも同じぐらいなので、
やはり何かほかに問題があるような気がします。
ところで
>分析ループする毎にインクリメントする適当な変数を入れ
>合計を稼働時間で割れば一秒あたりの処理数が出ますが、
>一秒間に7900/8000以上処理できています。
この辺をどうやってやってますか。
分析ループ中に時間が間に合わなければループを抜ける処理をやっているのでしょうか。
時間の測定方法は、timeGetTimeとかGetTickCountとか使っているのですか。
余りにも短い時間なので誤差によって正確に計算できない可能性があると思います。