Yuki Nakata's Blog

天才 中ちゃん♪

arimalobby

有馬グランドホテルに行ってまいりました。

日帰りプランです。

アクセスは南方面の夙川から車で30分。意外と近いんですね。

http://www.arima-gh.jp/dayplan/ticket.html

入場券付館内共通券というものです。

平日大人で3650円。これで温泉に入れて2000円分までレストランで食事ができます。

2000円を超えた場合は超えた分だけ有料になります。

ホテルに着くと和服のお姉さんが出迎えてくれます。
arimagarden


ホテル、庭園、温泉どれも見事です。

贅沢にお金が掛かっています。

ホテルの温泉というのも良いですね。

平日の午前中だったので客はほとんどいません。温泉をほぼ独占できました。

露天風呂も一人。人がいない温泉は本当に素晴らしいと実感しました。

11時から温泉につかり、12時に食事。

お寿司の和食と洋食を選べます。
arimalunch

今回は洋食にしました。

贅沢な気分に浸れました。

日帰りで良いのでたまにはこういうのもいいですね。大満足です。



radiko
ラズベリーパイでFM COCOLOや FM 802のラジオを聞きたいですよね。

ラズベリーパイを使えば1日中radikoを聞くことができますよ。1か月聞きっぱなしでもコストは電気代の約50円だけ。

しかも、スマホやPCからラズベリーパイのラジオをリモートコントロールできます。

21世紀的ですね。さっそくやってみましょう。

. mplayerとrtmpdumpをインストールします。

$ sudo apt-get install mplayer

$ sudo apt-get install rtmpdump swftools libxml2-utils

mplayerで持っている音声ファイルmp3の音が出るか試してみてください。

$ mplayer 音声ファイル.mp3

音が流れたら成功です。


2. play_radiko.shをダウンロード

play_radiko.sh シェルスクリプトを下のリンクからダウンロードしてください。
 https://gist.github.com/ihsoy-s/5292735

play_radiko.sh を編集します。
作成するディレクトリを指定します。

私はoutdirを下の変更しました。
outdir="/home/pi/radio/"

これで /home/pi/radio/ディレクトリが作成されるようになります。

$ sudo chmod +x play_radiko.sh

$ sudo cp play_radiko.sh /usr/bin/play_radiko.sh

3. ラジオを再生してみよう

試しにFM COCOLOを流してみましょう。
$ play_radiko.sh CCL 

FM 802を再生してみましょう。
$ play_radiko.sh 802

CCLがFM COCOLOです。802がFM 802。
ラジオ曲の放送局IDは以下のリンクで確認できます。
http://www.dcc-jpl.com/foltia/wiki/radikomemo
 
4. ブラウザからリモートコントロールしよう。
ラズベリーパイからラジオを再生することができたら、ブラウザからリモートコントロールできるようにしましょう。

ここまでは簡単でした。
実はここからが本題で、難しいかもしれません。

今回ここは解説を省略します。

IPアドレスを固定してウェブサーバーを立ててください。

私は軽量のnginxとphpでウェブサーバーを立てています。定番のapacheでもいいです。

IPアドレスは192.168.0.101にしています。

IPアドレスは毎回起動時に変動すると面倒なので固定IPアドレスにします。

5. ウェブサーバーから音を鳴らせるようにしよう。
ブラウザからコマンドを実行させて音を鳴るようにする必要があります。

$ usermod -G www-data, audio www-data
要するにウェブサーバーをaudioグループに追加しています。

apacheやnginx, ともにデフォルトでwww-dataになっていますので、これで良いと思います。

更新の仕方が分からないので、ここで一度再起動しました。

6. index.phpを作成しよう。

ウェブサーバーを無事に立てれたとします。

以下のphpをindex.phpで保存して、ウェブルートに置いてください。


<?php
//radiko player
//http://www.nakatayuki.com/


if(isset($_GET['id'])){

$id = $_GET['id'];
if($id=="stop"){
exec("killall mplayer");
}else if($id=="CCL"){
exec("killall mplayer");
exec("play_radiko.sh CCL", $e);
}else if($id=="802"){
exec("killall mplayer");
exec("play_radiko.sh 802", $e);
}else if($id=="ABC"){
exec("killall mplayer");
exec("play_radiko.sh ABC", $e);
}else if($id=="MBS"){
exec("killall mplayer");
exec("play_radiko.sh MBS", $e);
}else if($id=="OBC"){
exec("killall mplayer");
exec("play_radiko.sh OBC", $e);
}else if($id=="RN1"){
exec("killall mplayer");
exec("play_radiko.sh RN1", $e);
}else if($id=="RN2"){
exec("killall mplayer");
exec("play_radiko.sh RN2", $e);
}else if($id=="CRK"){
exec("killall mplayer");
exec("play_radiko.sh CRK", $e);
}else if($id=="KISSFMKOBE"){
exec("killall mplayer");
exec("play_radiko.sh KISSFMKOBE", $e);
}else if($id=="HOUSOU-DAIGAKU"){
exec("killall mplayer");
exec("play_radiko.sh HOUSOU-DAIGAKU", $e);
}
}
?>
<html>
<head>
<meta name="viewport" content="width=device-width">
</head>
<body>
<p><a href="index.php?id=stop">stop</a></p>
<ul>
<li><a href="index.php?id=802">FM 802</a></li>
<li><a href="index.php?id=CCL">FM COCOLO</a></li>
<li><a href="index.php?id=ABC">ABC Radio</a></li>
<li><a href="index.php?id=MBS">MBS Radio</a></li>
<li><a href="index.php?id=OBC">OBC Radio Osaka</a></li>
<li><a href="index.php?id=RN1">Radio NIKKEI 1</a></li>
<li><a href="index.php?id=RN2" >Radio NIKKEI2</a></li>
<li><a href="index.php?id=CRK" >CRK Radio Kansai</a></li>
<li><a href="index.php?id=KISSFMKOBE" >Kiss FM KOBE</a></li>
<li><a href="index.php?id=HOUSOU-DAIGAKU" >HOUSOU DAIGAKU</a></li>
</ul>
</body>
</html>
 
 radiko player
パソコンからラズベリーパイにアクセスしたところ。

IPアドレスにアクセスします。私の環境ではhttp://192.168.0.101 です。
ラジオ曲をクリックするとラジオの再生が始まります。
STOPで停止ができます。

ラズベリーパイでラジオライフを楽しんでくださあい。でわ。 

前回のlinuxで科学技術計算をしようの続きです。

円周率を1億桁計算しました!からのプログラムです。

pai.c


/* Calculate pi based on Chudnovsky algorithm (& Binary Splitting method), using GMP */
/* [1] Computation of 2700 billion decimal digits of Pi using a Desktop Computer,
       Fabrice Bellard, Feb 11 2010 (4th revision),
       http://bellard.org/pi/pi2700e9/pipcrecord.pdf */
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <math.h>
#include <time.h>

mpz_t A, B, C, C3over24;

void computePQT(mpz_t P, mpz_t Q, mpz_t T, int n1, int n2) {
  int m;
  if (n1 + 1 == n2) {
    mpz_t a;
    mpz_init(a);
    /* P(n2-1, n2) = - (2 * n2 - 1) * (6 * n2 - 5) * (6 * n2 - 1) */
    mpz_set_ui(P, (2 * n2 - 1));
    mpz_mul_ui(P, P, (6 * n2 - 5));
    mpz_mul_ui(P, P, (6 * n2 - 1));
    mpz_neg(P, P);
    /* Q(n2-1, n2) = C^3 * n2^3 / 24 */
    mpz_mul_ui(Q, C3over24, n2);
    mpz_mul_ui(Q, Q, n2);
    mpz_mul_ui(Q, Q, n2);
    /* a_n2 = (A + B * n2) */
    mpz_mul_ui(a, B, n2);
    mpz_add(a, a, A);
    /* T(n2-1, n2) = a_n2 * P(n2-1, n2) */
    mpz_mul(T, a, P);
    mpz_clear(a);
  } else {
    mpz_t P1, Q1, T1, P2, Q2, T2;
    mpz_init(P1);
    mpz_init(Q1);
    mpz_init(T1);
    mpz_init(P2);
    mpz_init(Q2);
    mpz_init(T2);
    m = (n1 + n2) / 2;
    computePQT(P1, Q1, T1, n1, m);
    computePQT(P2, Q2, T2, m, n2);
    /* P = P1 * P2 */
    mpz_mul(P, P1, P2);
    /* Q = Q1 * Q2 */
    mpz_mul(Q, Q1, Q2);
    /* T = T1 * Q2 + P1 * T2 */
    mpz_mul(T, T1, Q2);
    mpz_mul(P1, P1, T2);
    mpz_add(T, T, P1);
    mpz_clear(P1);
    mpz_clear(Q1);
    mpz_clear(T1);
    mpz_clear(P2);
    mpz_clear(Q2);
    mpz_clear(T2);
  }
}

int main (int argc, char* argv[]) {

  clock_t start, end;
  FILE* fp;

  int digits = 10000;
  int prec = digits * log2(10);
  int n = digits / 14;

  start = clock();

  mpf_t pi, temp;
  mpz_t P, Q, T;

  /* Initialize GMP numbers */
  mpf_set_default_prec(prec);
  mpf_init(pi);
  mpf_init(temp);
  mpz_init(P);
  mpz_init(Q);
  mpz_init(T);
  mpz_init(A);
  mpz_init(B);
  mpz_init(C);
  mpz_init(C3over24);

  /* Assignment */
  mpz_set_str(A, "13591409", 10);
  mpz_set_str(B, "545140134", 10);
  mpz_set_str(C, "640320", 10);
  mpz_mul(C3over24, C, C);
  mpz_mul(C3over24, C3over24, C);
  mpz_div_ui(C3over24, C3over24, 24);

  computePQT(P, Q, T, 0, n);

  /* pi = C ^ (1 / 2)     */
  mpf_set_z(temp, C);
  mpf_sqrt(pi, temp);
  /*      * C             */
  mpf_mul(pi, pi, temp);
  /*      * Q             */
  mpf_set_z(temp, Q);
  mpf_mul(pi, pi, temp);
  /*      / (T + A * Q)   */
  mpz_mul(Q, A, Q);
  mpz_add(Q, Q, T);
  mpf_set_z(temp, Q);
  mpf_div(pi, pi, temp);
  /*      / 12            */
  mpf_div_ui(pi, pi, 12);

  /* mpf_out_str(stdout, 10, digits, pi); */
  fp = fopen("output.txt", "w");
  if (fp == NULL) {
    printf("couldn't open output.txt");
    exit(EXIT_FAILURE);
  }
  end = clock();
  printf("%.3f s\n",(double)(end - start) / CLOCKS_PER_SEC);
  mpf_out_str(fp, 10, digits, pi);

  mpf_clear(pi);
  mpf_clear(temp);
  mpz_clear(P);
  mpz_clear(Q);
  mpz_clear(T);
  mpz_clear(A);
  mpz_clear(B);
  mpz_clear(C);
  mpz_clear(C3over24);

  end = clock();
  printf("%.3f s\n",(double)(end - start) / CLOCKS_PER_SEC);

  return 0;
}

桁を変更するには
int digits = 10000;

この箇所で変更してください。
1億桁にするには
int digits = 100000000;

10万桁からやってみましょう。
$ #10万桁
$ gcc pai.c -o pai -lgmp
$ ./pai
0.001 s
0.002 s

$#1億桁
$ gcc pai.c -o pai -lgmp
$ ./pai
147.206 s
180.558 s

1億桁がたった3分で計算できてしまいました。
MacBook Pro 2015 メモリ8Gです。
凄いパソコンを全く有効利用できていませんね。
プログラムの中身は後で読みたいと思います。ちゃんと読みますよ。 

linuxで科学技術計算をしよう。

科学技術計算をするためにgmpのインストールを行います。

sudo apt-get install m4 m4-doc

wget https://ftp.gnu.org/gnu/gmp/gmp-6.0.0a.tar.xz

tar -Jxvf gmp-6.0.0a.tar.xz

cd gmp-6.0.0

./configure --prefix=/usr/local

make

sudo make install

これでgmpがインストールされました。

簡単なサンプルをコンパイルしてみましょう。

プログラムモグモグさんの抜粋です。
test.c 

 #include <stdio.h>
#include <gmp.h>

int main (int argc, char* argv[]) {

  mpz_t a, b;

  mpz_init(a);
  mpz_init(b);

  mpz_set_ui(a, 12345);
  mpz_set_str(b, "12345678910987654321", 10);

  mpz_out_str(stdout, 10, a);
  printf("\n");
  mpz_out_str(stdout, 10, b);
  printf("\n");

  mpz_clear(a);
  mpz_clear(b);

  return 0;
}


コンパイルの仕方
$gcc test.c -o test -gmp

実行ファイルがtestでできあがります。

./test

12345
12345678910987654321

上の2行が表示されたら成功です。

 

XUB2390HS

液晶モニターの選び方です。

液晶モニターを選ぶときのポイントは絶対に目に優しいものを選ぶことです。

用語で言えばIPSパネル、フリッカーフリー機能などです。

アマゾンや価格コムで売れ筋上位のを選んでおけばまず間違いありません。

長時間パソコンを見ていると目が疲れます。

金を決してけちってはいけません。

液晶ディスプレイなんてもしかしたら10年間は使うかもしれないのです。慎重に選びましょう。


液晶ディスプレイのサイズは大きければ良い、というわけではありません。

大きければそれだけ顔や目を動かさなければいけません。もちろんマウスカーソルも。

しかもLEDライトを大量に浴びることになります。

サイズだけでもリアル店舗に行き確認をしておくべきでしょう。



私の使っているディスプレイはiiyamaのXUB2390HSです。

失敗しました。IIYAMAのディスプレイ事体は素晴らしいんです。

昇降スタンドで高さ調節、スウィーベル、90度回転、いろいろ機能が付いています。

ところがこのモデル、ヘッドホンジャックが付いていませんでした。買ってきてから気が付きました。

スピーカーは内蔵されていて音は出るのですが、ヘッドホンを繋げることができません。

大音量だと近所迷惑なので泣く泣く音量を下げて使っています。

こういうことがないようにしましょう。

ヘッドホンジャックが付いているものを選びましょうね。細かいことですが大事なポイントです。










 

flux1

パソコンにブルーライトをカットするf.luxを導入しよう。

PCの液晶画面からは眼に悪いブルーライトが出ています。

ソフトでブルーライトを軽減することができるf.luxをインストールしましょう。 

https://justgetflux.com/ 

上のページに行き、Download f.luxをクリックし、インストールします。

f.luxの設定の仕方。

flux

Changeボタンを押し、位置を指定します。

locationのところにtokyoと入力、Searchボタンをクリック。

OKを押したら完了です。

昼と夜とで明るさを選ぶことができますが、デフォルトのままで構いません。

Daytimeで6500K, At nightで3400Kとなっています。

この数値を低くするとディスプレイを暗くすることができます。

 

processinglifegame
以前、はむくんのライフゲームの世界を再現しようでライフゲームを再現しました。

今回はprocessingを使ってライフゲームを作成しましょう。

といっても他の人が作ってくれていますので、それを参考に改造していきます。

新米コンサルの日常 のライフゲームを改造しています。

このライフゲームでは2つのモードを設定しています。

セルを作成したり、削除するEditモードとライフゲームを動かすPlayモードです。

遊び方
起動すると最初にエディットモードになります。
マウスをクリックしてセルを作成してください。
スペースキーを押すとプレイモードとなります。
再びスペースキーを押すとプレイモードとエディットモードを切り替えることができます。

ゴスパーのグライダー銃も再現することができますよ。楽しめます。

final int SIZE_OF_CELL = 20;
final int FRAME_SIZE_OF_X = 800;
final int FRAME_SIZE_OF_Y = 800;
int num_of_row = FRAME_SIZE_OF_Y / SIZE_OF_CELL; //gyou  
int num_of_col = FRAME_SIZE_OF_X / SIZE_OF_CELL; //retsu
int num_of_cell = num_of_row * num_of_col;
Cell[][] cells = new Cell[num_of_row][num_of_col];
boolean game_state = false;


void setup(){
  size(FRAME_SIZE_OF_X, FRAME_SIZE_OF_Y);
  frameRate(20);
  for(int row=0; row<num_of_row; row++){
    for(int col=0; col<num_of_col; col++){
      int position_x = col * SIZE_OF_CELL;
      int position_y = row * SIZE_OF_CELL;
      cells[row][col] = new Cell(position_x, position_y, false);
    }
  }
  print("Edit Mode");
}

class Point{
  int row, col;
  Point(int my_row, int my_col){
    row = my_row;
    col = my_col;
  }
  int getRow(){
    return row;
  }
  int getCol(){
    return col;
  }
}

class Cell{
  int x, y;
  boolean state;

  Cell(int my_x, int my_y, boolean s){
    x = my_x;
    y = my_y;
    state = s;
  }
  
  void changeState(){
    state = !state;
  }
  
  void appear(){
    if(state){
      fill(34, 139, 34);
      //fill(50, 50, 50);
    }else{
      fill(50, 50, 50);
      //fill(255, 255, 255);
    }
    rect(x, y, SIZE_OF_CELL, SIZE_OF_CELL);
  }
}

void check_life_and_death(){
  ArrayList<Point> points = new ArrayList<Point>();
  for(int row=0; row<num_of_row; row++){
    for(int col=0; col<num_of_col; col++){
      //jibun no mawari check
      int num_of_alivers = 0;
      for(int r=-1; r<=1; r++){
        for(int c=-1; c<=1; c++){
          if(row+r<0 || row+r>=num_of_row || col+c<0 || col+c>=num_of_col){
            continue;
          } 
          if(cells[row+r][col+c].state){
            num_of_alivers++;
          }
        }
      }
      if(cells[row][col].state){ //jibun no bun wo hiku
        num_of_alivers--;
      }
      //joutai change no note
      if(cells[row][col].state){
        if(num_of_alivers<=1  || num_of_alivers>=4){
          points.add(new Point(row, col));
        }
      }else{
        if(num_of_alivers==3){
          points.add(new Point(row, col));
        }
      }
    }
  } 
  for(int i=0; i<points.size(); i++){
    Point point = points.get(i);
    int point_row = point.getRow();
    int point_col = point.getCol();
    cells[point_row][point_col].changeState();
  }
}

//random setup
void randomSetup(){
  //size(FRAME_SIZE_OF_X, FRAME_SIZE_OF_Y);
  frameRate(20);
  for(int row=0; row<num_of_row; row++){
    for(int col=0; col<num_of_col; col++){
      int position_x = col * SIZE_OF_CELL;
      int position_y = row * SIZE_OF_CELL;
      float coin_seed = random(1);
      boolean coin;
      if(coin_seed>0.8){
        coin = true;
      }else{
        coin = false;
      }
      cells[row][col] = new Cell(position_x, position_y, coin);
    }
  }  
}



void keyPressed(){
  
  
  if(key == ' '){
    game_state = !game_state;
  }
  
  if(game_state) {
    print("Play Mode  ");
  } else {
    print("Edit Mode  ");
  }
}

void mouseClicked(){
  int cell_col = mouseX/SIZE_OF_CELL;
  int cell_row = mouseY/SIZE_OF_CELL;
  cells[cell_row][cell_col].changeState();
  
  print("(" + cell_col + ",");
  print(cell_row + ") ");
}

void draw() {
  if(!game_state){
  }else{
    check_life_and_death();
  }
  for(int row=0; row<num_of_row; row++){
    for(int col=0; col<num_of_col; col++){
      cells[row][col].appear();
    }
  }
  //delay(500);
}

↑このページのトップヘ