CW練習 6/9

自作練習ソフトに驚愕の事実が判明しました。
音を出すルーチンを改良しているときに気が付きました。
これまでは短点・長点単位で音データをバッファに書き込んで音を出す、を繰り返していました。
public static void tone(int hz, int msecs, double vol) throws LineUnavailableException {
sdl.start();
for (int i = 0; i < msecs * 8; i++) {
double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
buf[0] = (byte) (Math.sin(angle) * 127.0 * vol);
sdl.write(buf, 0, 1);
}
System.out.println("size="+(msecs*8));
sdl.drain();
sdl.stop();
}
が、音が途切れる場合もあり、再生スピードによっては音が途切れる場合もありました。当初は javax.sound.sampled.AudioSystem の使い方がわかっていなかったのですが、最近、色々わかってきて以下のように文字単位でデータを書き込み、それを再生するほうがよいだろうと思って直しました。
public void tone(int hz, int msecs, double vol) {
//System.out.printf("tone hs=%d msecs=%d vol=%f\n", hz, msecs, vol);
int bufSize = msecs * 8;
byte[] buf = new byte[bufSize];
for (int i = 0; i < bufSize; i++) {
double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
buf[i] = (byte) (Math.sin(angle) * 127.0 * vol);
}
System.arraycopy(buf, 0, mainBuf, mainBufPos, bufSize);
mainBufPos = mainBufPos + bufSize;
//System.out.printf("bufSize=%d mainBufPos=%d\n",bufSize, mainBufPos);
}
それは良かったのですが、ふと見ると文字と文字の間で以下を呼び出していることに気が付きました。
public void whitespace_word() {// 語間スペース
try {
Thread.sleep(7 * multiplier);
} catch (Exception e) {
// TODO: handle exception
}
}
本当は 7 じゃなくて 3 が正しい。つまり今まで連続して文字を聞いた場合でも結構余裕があったということになります。他の送信サンプルを聞くと若干文字間が狭いなあ、とは感じていたのですが。。
修正後のソフトで練習すると、5文字連続は取れなくなってしまいました。うーむ。また2文字から練習し直しです。
ソフトは以下からダウンロードできます。
自分用なので他人が使用する前提で作っておりません。実行には Java が必要です。Windows10 のみで動作確認済み。音と文字を出力するのみで、入力(採点)機能はありません。音を聞いてノートやエディタに文字を書いてください。苦手な文字は CWgenerator.properties に記載します。速度は値を小さくすると早くなります。[聞く] ボタンにデフォルトフォーカスを設定してあるので答えをノートに書きながらスペースキー押すだけで答えを見て次の音を聞くことができます。
WS005.JPG