Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

rasperry PiでUSBオーディオ認識

前回、ラズパイでのpythonで音声出力の方法を記載しました。
elsammit-beginnerblg.hatenablog.com



しかしながらこちらの手順だけでは、
装着されたオーディオの識別順とかを考慮していなかったために
イヤホンジャックやHDMIUSBオーディオ
と複数デバイスが装着された状態だと、意図しないデバイスから音声が出力される場合があります。

。。。すっかり抜けていた。。。泣




今回はオーディオデバイスの指定方法やデフォルトとなるデバイスの入れ替え方法などを書いていきたいと思います!!
f:id:Elsammit:20200803204450j:plain




■オーディオデバイスの指定方法
まず識別しているデバイス情報を確認します。
確認のコマンドはこちらです。

aplay -l

こちらを実行すると

**** ハードウェアデバイス PLAYBACK のリスト ****
カード 0: ALSA [bcm2835 ALSA], デバイス 0: bcm2835 ALSA [bcm2835 ALSA]
  サブデバイス: 7/7
  サブデバイス #0: subdevice #0
  サブデバイス #1: subdevice #1
  サブデバイス #2: subdevice #2
  サブデバイス #3: subdevice #3
  サブデバイス #4: subdevice #4
  サブデバイス #5: subdevice #5
  サブデバイス #6: subdevice #6
カード 0: ALSA [bcm2835 ALSA], デバイス 1: bcm2835 IEC958/HDMI [bcm2835 IEC958/HDMI]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
カード 0: ALSA [bcm2835 ALSA], デバイス 2: bcm2835 IEC958/HDMI1 [bcm2835 IEC958/HDMI1]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
カード 1: MicroII [Audio Advantage MicroII], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

というように、カード番号とサブデバイス番号が取得できます。

上記結果の場合には、USBオーディオバイスは、
・カード:1
・サブデバイス:0
となります。


カード番号とサブデバイス番号がわかったら、音声コマンド実行時にオプションとしてデバイス情報を付与すればOK!!
付与の仕方はコマンドによりそれぞれだが、大体は

hw:カード番号,サブデバイス番号

でOKかと。

例えば、aplayコマンドやmpg321コマンドの場合には、

aplay -D hw:1,0 音声ファイル名.wav
mpg321 -a hw:1,0 音声ファイル名.mp3

とすればよいです。


■デフォルトデバイス切り替え方法

まずはデフォルトで設定されているデバイスの確認ですが、こちらのコマンドを実行すると確認できます。

cat /proc/asound/modules

今回実施してみたところ、

 0 snd_bcm2835
 1 snd_usb_audio

となりましたので、USBオーディオは2番目に認識することになります。


snd_usb_audioを1番に変更したい場合には、
/etc/modprobe.d/alsa-base.conf
を修正(もしくは新規作成して)

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

とすればOKです。


■最後に

alsa-base.conf修正時に文字入力ミスをしてしまい、結構ハマってしまいました。。。
急にaplayコマンドを使用しても、USBオーディオが認識しなくなってしまい、かなり焦った。。。

入力ミスには気を付けていきたいです。

githubでReact作成したWebアプリ・Webサービス公開

最近簡単なアプリを作成してそれをブログで報告してきましたが、
とある友人より、


面白そうだから使って見たいな!!


という、酔狂なことを言われました。



はてなブログだとソースコードは載せられても実際にWebアプリは動かせないもんな、、、
と思いつつ、ネットサーフィンを楽しんでいたところ。。。


ある方法を思いつきました!!
そう、Githubで公開してしまえばよいのだと!!



早速調べてみることに。


githubの「GitHub Pages」の機能を有効化すればよいことがわかりました。
この機能を有効化すると指定したブランチ直下のindex.htmlを読み込んでページとして表示してくれる機能になります。


実際にGitHub Pagesを用いて作成したWebサービスがこちらになります!!
※友人に使って見たい、と言われたモグラたたきアプリになります。
https://elsammit.github.io/Moguratataki/elsammit.github.io






今回は、Reactで「GitHub Pages」を用いてwebアプリの公開手順について備忘録残しておこうと思います!!


GitHub Pages設定手順

そもそも、GitHub Pagesって何もの?と思い調べたところ、

GitHub上で管理しているリポジトリについて、静的なページとしてホスティングしてくれるサービス。
とのことです。

大まかな手順は、
GitHub上にリポジトリを作成
webサービスをpush
GitHub Pagesを設定

となります。
①、②はGitHubの使い方になってしまうため省略して、③について記載していきます。

まず作成したリポジトリを選択し、Settingsを選択します。
f:id:Elsammit:20200802172853p:plain


Settingsのページを下にスクロールさせていくと、GitHub Pagesという項目があります。
こちらのSource項目のBranchを選択しSaveボタンを押下します。
f:id:Elsammit:20200802173445p:plain


設定はこれで終了!!
設定すると、GitHub Pages用のURLが生成されるので、こちらにアクセスするとWebサービスが表示されます。



■ReactでのWebページ表示

先ほど記載した通り、GitHub Pagesはリポジトリ直下のindex.htmlを読み込んでページを表示します。
一方Reactは、こちらのようなディレクトリ構成になります。
f:id:Elsammit:20200802174054p:plain


このままではGitHub Pagesを用いてWebサービスを表示させることはできません。


そこで用いるのが、

yarn build

もしくは

npm run build

になります。

こちらを実行すると、buildディレクリが新規で生成され、buildディレクトリの中にindex.htmlファイルを含む、
パフォーマンスが最適化されてた生成物一式が保存されます。


このbuildディレクトリ直下のファイル・ディレクトリ群一式を作成したリポジトリ直下にpushすればよいです。


実際にpushした際の表示はこちらのようになります。
f:id:Elsammit:20200802174938p:plain


この状態で先ほど設定したGitHub Pagesで生成されたURLを指定すると、、、
無事、Webサービスが表示されます。


■最後に

結構簡単にWebサービスの表示が行えるな、と思いました。
ただ、、、
当初作成したwebサービスのレイアウトだと、スマホで画面がズレることが判明!!泣
スマホでもきれいなレイアウトにするために調整してたけど、結構大変だった。。。
これからは作る時にはそこらへんも意識して作っていきたいな!と思いました。


React chatbotアプリ作成

Reactで面白そうなアプリ作れないかな??と思い考えていたのですが、、、

Chatbotとか作れたら面白そうだな!!

と思いたち早速作成することにしました。



React Chatbotで調べてみたところ、
react-simple-chatbot
というライブラリを用いると簡単に作れそうなことを発見。

実際に使ってみたので、その結果を報告します!!




実際に作成したchatbotはこんな感じです。
f:id:Elsammit:20200801193202g:plain






f:id:Elsammit:20200801205755g:plain





今回作成した部分はメッセージのやり取りだけで、デザインはreact-simple-chatbot自体のデフォルトを用いております。


まずはreact-simple-chatbotライブラリのインストール手順から。

と言ってもこちらを実行してライブラリインストールすればOK!!

npm install react-simple-chatbot


こちらが公式で公開されているコードです。

<ChatBot
  steps={[
    {
      id: '1',
      message: 'What is your name?',
      trigger: '2',
    },
    {
      id: '2',
      user: true,
      trigger: '3',
    },
    {
      id: '3',
      message: 'Hi {previousValue}, nice to meet you!',
      end: true,
    },
  ]}
/>


こちらをReactに組み込むために、chatbot.jsファイルを作成し、
こちらのように実装。

import React, { Component } from 'react';
import ChatBot from 'react-simple-chatbot';

export default class chatbot extends Component  {

    render() {
        var msg = "";
        return (<ChatBot
            steps={[
              {
                id: '1',
                message: 'What is your name?',
                trigger: '2',
              },
              {
                id: '2',
                user: true,
                trigger: '3',
              },
              {
                id: '3',
                message: 'Hi {previousValue}, nice to meet you!',
                end: true,
              },
            ]}
          />
    )}
}

そして、index.jsに対して

ReactDOM.render(
  <React.StrictMode>
    <Chatbot />
  </React.StrictMode>,
  document.getElementById('root')
);

というように実装してこちらを実行すれば

npm start

こちらのような名前を尋ねるchatbot画面が表示されます。
f:id:Elsammit:20200801202601p:plain




チャットボットのやり取りですが、
 ・id変数:1番からの実行順(1以降はtrigger変数に設定されたidが実行)
 ・message変数:記載されたメッセージが出力
 ・trigger変数:設定されたidが次に実行される
で定義されております。

また、message変数をやり取りした内容により切り替えたい場合にはこちらのように関数化すればよいです。

message: ()=>{
    const {name} = this.state;
    const {ID} = this.state;
    var ret = 'こちらで登録します   名前:' + name + '    ID:' + ID;
    return ret;
}


入力された値を判定したり、処理したり、変数をメンバ変数に格納したりする場合にはこちらのvalidatorを用いればよいです。

validator:(value) => {
    this.setState({
        ID: value
    });
    return true;
},

別関数実行したい場合もvalidatorやmessageを関数化してその中で実行すればよいです。

validator:(value) => {
    var ret = this.renderText(value);
    if(ret){
        flg=1;
        console.log("test is ",test);
        return true;
    }else{
        flg=0;
        console.log("test is ",test);
        return true;
    }
},


これらの処理を組み合わせてtriggerとidにより処理順を決めていけばchatbotが作れるようになります。




最後に、、、
こちらに作成したソースコードを格納しました!!
https://github.com/Elsammit/chatbot.git



今回は実施しませんでしたが、
前回のサーバサイドとの通信方法を用いれば、ユーザが入力した内容に応じて
 ・サーバへデータを書き込み
 ・サーバからデータを読み出し
ができるようになるかと思います。



もっと面白もの、便利なもの、を作成したいな!!と思うのですが、、、
思いつかない。。。泣

面白そうなネタ探してみたいと思います!!

ジョブ型雇用で日本の働き方が変わるのか?

最近コロナウィルスが影響でテレワークや時差出勤など働き方が変わっていますね。
私の会社でもテレワークが推進されて半年が経とうとしております。


そんな中、日立や資生堂富士通などの大手企業が「ジョブ型雇用」を導入しましたね。

■ジョブ型雇用とは?

従業員に対して職務内容を明確に定義し、労働時間ではなく成果で評価する雇用制度のこと
欧米諸国で広く普及している。


対比で用いられる雇用形態として「メンバーシップ型雇用」です。

■メンバーシップ型雇用

職務内容や勤務地を限定せず、スキルよりも会社に合う人材を雇用する制度のこと



ジョブ型雇用、、、
何となく意味は分かっていましたが、今回を機に特徴やメリット、デメリットについて調べたのでまとめておこうと思います。

■ジョブ型雇用の特徴

参考にさせて頂いたサイトにジョブ型雇用の特徴がまとめられておりました。
f:id:Elsammit:20200731223741p:plain
※参考:https://sogyotecho.jp/jobgatakoyou/



他にも、、、
・職務内容が職務記述書(ジョブディスクリプション)に則って行われる
 ⇒該当ポジションの職務内容・職務の目的・必要スキルなどが明確

・基本的に異動・転勤がない

・業務成果に応じた給与

・人材の流動性が高い


などの特徴があるようです。

■ジョブ型雇用のメリット

・専門性の高い人材を採用できる。専門分野の人材を育てていきやすい
・専門職の仕事に集中しやすいため、スキルを磨きやすく自分の得意分野・学んでいきたい分野に集中しやすい

■ジョブ型雇用のデメリット

・業務内容によっては、仕事がなくなる = 解雇になる可能性がある
・職務記述書に記載のない業務を任せられないため、会社都合で人材の配置換えが行えない
・組織の柔軟性が損なわれる

■なぜ広まりを見せたのか?

今までのメンバーシップ雇用や働き方の場合、労働時間に応じて給与を支払うという考えが主流であり、従業員を管理・評価することになります。
要するに、「君、いつも頑張ってるから給料奮発しちゃうよ!」って感じですかね?


しかしながら、昨今のコロナウィルスの影響でテレワークや時差出勤が主流になってきてしまい、今までのような管理・評価のやり方が通じなくなってしまいました。
今までのように「頑張っている子がだれで、サボっている子がだれか」監視できなくなってしまったので、甲乙つけられない!!ということでしょうね。


さらに、デジタル変革(DX)が加速度的に進んでいる現在で、DXを主導できる優秀なIT人材を自社で育成することが難しくなっていることも要因のようです。
「デジタルの時代に日本企業が生き残る上で、極めて重要な取り組み」のようです!!


■個人的な思い

ここまで書いてみて思ったけど、、、日本で通用していくのかな???と思ったのが本音です。



今まで終身雇用や年功序列制度などの制度や働き方により、
会社に入るとレールの上を走る機関車のように働けていたのに、急にレールが取り外されるってことですよね??
急に、「明日からジョブ型雇用にするから働き方変えて!!」と言われて柔軟に対応できる人、少ないと思います。



会社に入るといつかは昇進し給料が上がることを餌に若い頃より滅私奉公してきた世代はどう考えるでしょうか??
管理・評価する立場が上で書いた世代となっているため、まずはそこの意識改革が必要になってくるかと思います。



また、中小やベンチャー企業は従業員が限られているので、掛け持ちで業務を行うことが多くなります。
ベンチャーの場合には行う事業も流動的になってしまいがちなので、業務が大きく変わる可能性もあります。
このような条件下でジョブ型雇用が行えるのか??疑問が残ります。


さらにさらに、新卒一括採用を扱いがどうなるのか?も大いに疑問です。



どうしても課題が大きくかつ、多いので、
コロナウィルス起因の一過性の考え、 or ある一部の雇用形態で終わってしまう気がしてならないです。。。
日本全体に広がるのはまだまだ先の話。。。な気がしている今日この頃。



個人的には会社・企業の中でどう立ち回るかしか考えられない今の形態より、より広く物事を考え、
自分の方向性を考え、自ら選択しながら働けるジョブ型には大変興味を持ちます。

React サーバサイドとの通信

前回書いたSPAを実際に動かしてみるための前段階として、
サーバサイドとの通信をしてみたいと思い試しに動かしてみたところ躓いたため備忘録で残そうと思います!!
elsammit-beginnerblg.hatenablog.com



まずReactでget、postリクエストを行うためにはaxiosを用いるためインストールを行います。
[フロントエンド] axiosライブラリを使って、柔軟にHTTP通信を行う - YoheiM .NET

yarn add axios

そして、実際にReactを用いてサーバサイドにgetを行うためにこちらを作成し実行!!

import React, { Component } from 'react';
import axios from 'axios' 

export default class Todo extends Component  {

    constructor (props) {
        super(props);
        this.state = {
            name: 'yahoo',
        };
    }

    Clcik = () => {
        const url = "http://192.168.56.101:8080";
        axios.get(url).then((res) => {

          this.setState({
            name: res.data
          });
        });
      }

    render() {
        const {name} = this.state;

        return(<div>
            <h1>&nbsp;
                <u>テスト</u>
                <h3>{name}</h3>

                <button onClick={this.Clcik}>Click!!</button>
            </h1>
            </div>
        );
    }    
}

こちらは実行すると{name}の部分がyahooからサーバサイドから取得したデータを表示する、
そんな簡単なものになります。

そして、、、こちらで動作させてみたところ、、、

axios as been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

といったエラーが発生し、サーバサイドへget requestが送れない。。。泣



なぜだろうと思い、調べてみたところ、
どうやら、Cross Origin Resource Sharing(cors)が必要になるとのこと!!
corsに悩まされるな。axios でcorsを攻略する - Qiita


そこで、記事に書かれている通り下記を追加。

axios.defaults.headers.get['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.get['Access-Control-Allow-Origin'] = '*';
axios.defaults.withCredentials = true; 

合わせて、こちらをサーバサイド側に実装する必要があったためまずはパッケージをインストールして、

npm install cors

次に下記をサーバサイド側に実装。

var cors = require('cors')
app.use(cors({ origin: true, credentials: true }));


無事エラー解消させることができました!!


corsについて理解できていない点があるため、これから調べてまとめてみたいと思います!!



■参考
サーバサイド側の実装はこちらになります。

const express = require('express');
const app = express();
var cors = require('cors')
app.use(cors({ origin: true, credentials: true }));

app.get('/', (req, res) => {
  console.log("bbb");
  res.send("<h1>Welcome</h1>");
});

app.listen(8080, ()=> {
  console.log("Listening: 8080");
});

raspberry Pi でのpythonを用いた音声出力

今回は今までの流れとガラッと変えて、raspberry Piでの音声出力です。

ちょっと必要になり調べたので備忘録として残しておこうと思います!!


実行言語はpythonですので、pythonで実行できる音声出力方法を調べました。

調査した結果、使いやすそうだったのはこちらです。
 ・aplay
 ・pygame
 ・mpg321


■aplay
ラズパイ上でこちらのコマンドを実行すると音声出力されます。

aplay 音声ファイル名.wav

ここでapalyは、、.mp3は再生できません!!
.wavファイルであれば問題なく再生されますが、.mp3は雑音が出てきます。
※知らずに爆音で流してしまい、びっくりしました。。。心臓に悪い泣



pythonで実行する場合には、subprocessを用いて、このように実行すればよいです。

import subprocess

subprocess.call("aplay 音声ファイル名.wav", shell=True)


pygame
pygamepythonでコンピュータグラフィックスと音声を扱うためのライブラリとのことです。
ゲーム作成に用いるライブラリのようです。
pygameであれば.mp3も再生できます。
pythonでの実行は下記で行えます。

import pygame.mixer
import time

pygame.mixer.init()
pygame.mixer.music.load("音声ファイル名.mp3") ←.wavファイルも再生可能です。
pygame.mixer.music.play(1) ←music.playの引数が再生回数です。 -1を設定すれば無限ループが可能。

time.sleep(10)       ←pygameはマルチスレッドで動作するようでsleepさせておかないと再生された瞬間に次の処理(Stop)が実行.
pygame.mixer.music.stop()

 
■mpg321
mpg321はraspberry Piに標準でインストールされていないため、下記を実行しパッケージをインストールする必要があります。

sudo apt-get -y install mpg321

mpg321もコマンドとして実行ができ、raspberry Pi上でこちらを実行すれば音声再生できます。

mpg321 音声ファイル名.mp3

こちらはaplayと逆で、.mp3は再生できますが、.wavは再生できない(雑音が出力されます)です。
pythonで実行する場合には、subprocessを用いて、このように実行すればよいです。

import subprocess

subprocess.call("mpg321 音声ファイル名.wav", shell=True)

■まとめ
先ほどの3種類の方法をまとめるとこちらになります。
f:id:Elsammit:20200728224047p:plain 


■最後に
音声出力だけでも様々な種類があって調べていて面白かったです。
出力するファイルに応じて使用する方法も切り替えていきたいな、と思いました。

ついでに、、、
pyAudio
という手段もあるのですが、
ストリーミング配信として主に用いられているようですし、.mp3が再生できないようでした。
また、ちょっとしようするのにパラメータが多く、簡単に使えそうになかったので除外しました!!


■参考
Raspberry Piで音楽(wav/mp3)ファイルを再生する方法 python編 - Qiita

アロー関数とは?

Reactを使っているとアロー関数を結構多用します。
このアロー関数の書き方がjavascript独特の書き方なので、特徴や使い方、利点とかを調べてまとめてみようと思います!!

目次

■アロー関数とは

ES2015(ES6)から利用可能になった新しいJavaScriptの構文の一つ。
このES6のタイミングでletによる変数宣言やpromiseによる非同期処理の実装ができるようになったようです。
※ES6は大幅に構文追加があったようですね。

アロー関数は下記のように"=>"を用いて関数式を記載する方式です。

let arrowFunc = (val) =>{
 console.log(val);
}

arrowFunc('test');

アロー関数が実装可能になるまではこちらのように書く必要があったため、"function"を書かなくてよくなった分簡潔に書くことができるようになっていますね。

let Func = function(val){
 console.log(val);
}

Func('test');

■アロー関数の特徴

先ほど書いた通り、"function"を書かなくてよいので簡潔に書けるようになっているのですが、
今回のようにconsole.log()のみのように1行であればこちらのように括弧書きも不要になります。

let arrowFunc = (val) => console.log(val);


1行であればより簡潔に書けますので、すっきりしますね!!



さらに、アロー関数でthisを用いた場合には一般的なfunctionとは挙動が異なります。


例えば、、、
こちらのような書き方をした場合、

val = 'global parameter';

function OutputValue(){
    console.log(this.val);
}

let Obj = {
    val: 'Obj parameter',
    func: OutputValue
}

OutputValue.func();


実行結果はこちらのようになります。

Obj parameter

要するにfunc実行時にObjで設定したObj parameterがval変数にセットされ、console.logで出力されたことになります。


一方、こちらのような書き方をした場合、

val = 'global parameter';

let OutputValue = () => {
    console.log(this.val);
}

let Obj = {
    val: 'Obj parameter',
    func: OutputValue
}

OutputValue.func();

実行結果はこちらのようになります。

global parameter

先ほどの結果と変わっていることがわかります。
どうやらアロー関数で宣言した関数はコールされた時点でのthisを確定させてしまうようです。
呼び出し元がどこであろうと同じ結果が得られる、ということですね。


■Reactでアロー関数を用いる理由

ここまでで、アロー関数とthisの値が普通の関数と異なることがわかりました。

Reactではこちらのようにコールバック関数をアロー関数で書きます。

export default class Calc extends Component  {
~~
onInput = (e) => {
    const {num} = this.state;
    var calcNum = 0;
    if(num == 0 ){
        calcNum = e.target.value;
    }else{
        calcNum = Number(num)  + e.target.value;
    }
    
    console.log("calcNum is " + calcNum);

    this.setState({
        num: calcNum
    });
    document.getElementById("CalcResult").value = calcNum;
}
~~

こちらの関数で使用されるthisはアロー関数で記載されるので、thisの値はCalcになります。


もしアロー関数で書かなかった場合、すなわちこちらのように実装した場合、

export default class Calc extends Component  {
~~
fuintion onInput (e){
    const {num} = this.state;
    var calcNum = 0;
    if(num == 0 ){
        calcNum = e.target.value;
    }else{
        calcNum = Number(num)  + e.target.value;
    }
    
    console.log("calcNum is " + calcNum);

    this.setState({
        num: calcNum
    });
    document.getElementById("CalcResult").value = calcNum;
}
~~

thisは未定義になってしまうため、これで動かそうとするとエラーになってしまいます。



これらのことから、
アロー関数を用いることでthisを定義しているclassで明確に定義することができるようになるため、コールバック関数はアロー関数で書くことが多くなります。



■最後に

アロー関数やthisの取り扱いについて、あいまいな部分があったなと書いていて感じました。
Outputすることって重要ですね。

これからも疑問に思った点は調べて、Outputしていきたいと思います!!