最近音声認識が凄いときいて、これも出来ないかな、と思いましたというお話し

英語上達完全マップって本があると聞いた

ソースは失念したが(Twitterを漁るとあるが)英語学習でこれが素晴らしい、という本があるそうだ。それがこれ。

英語上達完全マップ―初級からTOEIC900点レベルまでの効果的勉強法
英語上達完全マップ―初級からTOEIC900点レベルまでの効果的勉強法
作者: 森沢 洋介
出版社/メーカー: ベレ出版
発売日: 2005-10
売上順位: 2229

ちなみにAmazonの書評には公式Webサイトに内容が全部あるからそれ読めば?とあったのだが、なかなか筋が通っていて手法として面白そうなので書籍も買って読みました。

ああ、多少はやる気を損ねないな、たぶん確実に身につけられる手法だろうなぁ(少なくとも英会話学校やラジオ講座よりは効果的だわ)と思いまして。

(どうせ語学ができる人たちからは「そんなに屁理屈こねずラジオでもやれば良いのに」って言われるんだが、それが今まで身に付いたためしがないから、よりよい手法がないか、探してるんじゃないか…)

というかですね、日本の語学は非常にマッチョに「ひたすら精神論で頑張れ」だけれど、英語教育ってEnglish as a second languageとか、後から学習する人のための理論が用意されているそうだけれど、日本のでそういう理屈聞いたことないじゃない…という不満はずっとあったわけなんですが、ああナルホド、不足するポイントを的確に刺激するのね、とこの本には感銘を受けたわけです。

基本中の基本は「リピーティング」と「シャドーイング」、加えて「簡単な英作文を暗唱」だそうだ

この本によれば、やはり「聞いているだけ」までの楽はできない。

でも、中学校のテキストレベルの英文でもよいので、「リピーティング」、1音節ずつ話すのを追いかけて語る、「シャドーイング」、話しているのを聞きつつ追いかけて話す、をすればそれだけでかなり改善されるんだとか。

加えて、単純な文章の英語訳を暗唱するだけでも凄く強化されると。

おおう、おう、確かに足りないところはそこだわ!

でもさー教室に通いたくない、って気持ちは分かるよね

英語の勉強と同じような優先度の事象が沢山ある中で、「この手法を使ってくれる」まで気を遣ってくれる英語の先生なんて雇えないわけですよ。どっかの社長みたいに「海外の営業が必要だから」といって業務を半分以上捨てて英語プレゼン練習してた人はいますがそこまで僕は偉くはない。ってかそういう会社でええんだっけ、って話がそれた。

そういえば、googleさんの音声入力が強化されたよね

ということを考えていたのが2016年の夏前なんですが、当時いた会社で「いやー音声入力が発達して資料を口述で作れるわー」と言われ、まあ精密な資料を作る必要がなければそうかもね、俺の場合キーボードの方が早く作れるわ…と思いつつ、はたと気づく。

PCに例文をしゃべらせて、同時に話している自分の言葉を音声認識させれば、対面の恥ずかしさもなく、非常に機械的に英語が話せているかを判断してくれるじゃない!

という分けでググると、ブラウザアプリでもテキスト読み上げと音声認識、両方できることが分かる。

素晴らしいですね世界。

いや、テキスト読み上げは普通にあるとは思ってた。音声認識も同じようにAPIがあるなんて!

ブラウザのみで音声認識とテキスト読み上げを実現する Web Speech APIに丁寧なサンプルコードつきである。

ちょっと無くなるといやだからサンプルコピペしておきますね。

読み上げる方

var synthes = new SpeechSynthesisUtterance();
synthes.voiceURI = 'native';
synthes.volume = 1;
synthes.rate = 1;
synthes.pitch = 2;
synthes.text = 'No Programming, No Life';
synthes.lang = 'en-US';
synthes.onend = function(e) {
    alert('Finished in ' + event.elapsedTime + ' seconds.');
};
speechSynthesis.speak(synthes);

パラメータの詳細はWeb Speech API Specificationを見よとのこと。

音声認識する方

<div class="recPlayer">
    <div class="recPlayer__tools">
        <button class="recPlayer__recBtn">録音</button>
    </div>
    <div class="recPlayer__results">
        <ul></ul>
    </div>
</div>
window.SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
var Recorder = {
    recognition : null,
    init: function(){
        var o = this;
        o.recognition = new SpeechRecognition();
        o.recognition.lang = 'ja';
        o.recognition.continuous = true;
    },
    recStart: function(){
        var o = this;
        o.recognition.start();
    },
    recStop: function(){
        var o = this;
        o.recognition.stop();
    },
    getRecText: function(results, resultIndex){
        var text;
        for(var i = resultIndex; i < results.length; i++){
            var result = results.item(i);
            if(result.final === true || result.isFinal === true){
                text = result.item(0).transcript;
            }
        }
        return text;
    }
}
var Speeker = {
    synthes: null,
    init: function(){
        var o = this;
        o.synthes = new SpeechSynthesisUtterance();
        o.synthes.lang = "ja-JP"
    },
    say: function(msgText){
        var o = this;
        o.synthes.text = msgText;
        speechSynthesis.speak(o.synthes);
    }
}
var View = {
    getResultItem: function(text){
        var el = document.createElement('li');
        el.textContent = text;
        return el;
    }
}
var App = {
    el: {
        recBtn: $DEMO[0].querySelector('.recPlayer__recBtn'),
        resultList: $DEMO[0].querySelector('.recPlayer__results ul')
    },
    status: {
        nowRec: false,
        recorderText: ''
    },
    init: function(){
        var o = this;
        Recorder.init();
        Speeker.init();
        Recorder.recognition.addEventListener('start', function(){
            o.status.nowRec = true;
            o.el.recBtn.textContent = '停止';
        });
        Recorder.recognition.addEventListener('end', function(){
            o.status.nowRec = false;
            o.el.recBtn.textContent = '録音';
        });
        Recorder.recognition.addEventListener('result', function(event){
            var text = Recorder.getRecText(event.results, event.resultIndex);
            o.el.resultList.insertBefore(
                View.getResultItem(text),
                o.el.resultList.firstChild
            );
            Speeker.say(text);
        });
        o.el.recBtn.addEventListener('click', function(){
            if(o.status.nowRec){
                Recorder.recStop();
            }
            else{
                Recorder.recStart();
            }
        });
    }
}
App.init();

あとやることは

  • リピーティングっぽく話す読み上げAPIの叩き方
  • どこかにあるであろう英文の例文集(日本語文はgoogle翻訳にやらせよう)

の2点だなと思ったところで時間切れで1年弱経過して今日に至る。

例文の翻訳はGoogleがいいのかMicrosoftがよいのか

例文はESL: English as a Second Languageが 無料で転がってるしひどくなさそうなのでこれでよいか、と。

で、Google翻訳APIは有料化されてしまったのでMicrosoftと比較して みるかーってことで 前述のサイトの1個の例文 を翻訳して比較してみました。

訳文を比較してみた

意外とどっこいどっこいの性能だった。

Microsoft Translatorもnode.jsから叩けば使えるそうです。