2014年10月17日金曜日

Raspberry Pi I2S (8)

半導体計測屋さんが、RaspberyyPiからFSLED信号を出すスクリプトとタンデム基板の設定を公開された。ハードだけでなくLinuxのスクリプトまで書いてしまうとは!凄い!TypeBでもTypeB+でもOK。

441,96,192のリサンプリング設定読み込んで、NB3N2302の4倍8倍を自動切替してくれるので、一々タンデム基板の設定を変える必要がなくなる超便利スクリプトだ。なお、リサンプリング無しは441固定。441,96は4倍で22MHz、49MHz、192は4倍で49MHz。



SSHでvolumioにログインする
username : root
password : volumio


◆ How to install python

root@volumio:~# vi /etc/apt/sources.list
/wq


root@volumio:~# apt-get update
root@volumio:~# apt-get -y install python-rpi.gpio python-daemon


◆ How to install  start up daemon

root@volumio:~# vi /etc/rc.local
/wq


root@volumio:~# vi /home/volumio/mpc_FSLED.py

#!/usr/bin/python
#-*- coding: utf-8 -*-
u'''
http://www.rpiblog.com/2012/09/using-gpio-of-raspberry-pi-to-blink-led.html
https://github.com/if1live/rpi-mpd-controller
http://nw-electric.way-nifty.com/blog/2014/01/volumio-1ad0.html
http://zx900a.blogspot.jp/
'''

''' How to install python
    SSH login username:root password:volumio
/etc/apt/sources.list file OPEN and ADD this line
deb http://archive.raspberrypi.org/debian/ wheezy main
    type ther lines
sudo apt-get update
sudo apt-get -y install python-rpi.gpio python-daemon
'''
''' How to install  start up daemon
/etc/rc.local file OPEN and ADD this line befor "exit 0"
/usr/bin/python /home/volumio/mpc_FSLED.py

mpc_FSLED.py file place under /home/volumio
  type this line
chmod 777 mpc_FSLED.py
  type this line
reboot
'''
import RPi.GPIO as GPIO
import time
import commands
import re
from daemon import daemon
from daemon.pidlockfile import PIDLockFile

PIN_PREV_BTN = 15
PIN_PLAY_BTN = 10
PIN_NEXT_BTN = 8
PIN_STOP_BTN = 7
PIN_VOL_UP_BTN = 11
PIN_VOL_DW_BTN = 13

PIN_FS0 = 16
PIN_FS1 = 18
PIN_FS2 = 22


class Player(object):
    def __init__(self):
        self.re_play = re.compile(r'^\[playing\].+$')
        self.re_vol = re.compile(r'^volume:.+% .+$')
        self.play_state = self.is_playing()
        self.shutdown_timer = 0

    def sdtimer(self):
        if self.shutdown_timer is not 0:
            self.shutdown_timer -= 1

    def is_playing(self):
        result = commands.getstatusoutput('mpc')
        line_list = result[1].splitlines()

        playing = False
        for line in line_list:
            if self.re_play.match(line) is not None:
                playing = True

        self.play_state = playing

        for line in line_list:
            if self.re_vol.match(line) is None:
                self.vol_state = False
#                print '## vol False'
            else:
                self.vol_state = True
#                print '## vol True'

        return playing

    def play(self):
        if self.is_playing():
            retval = commands.getoutput('mpc pause')
            self.play_state = False
            print '#pause'
        else:
            retval = commands.getoutput('mpc play')
            self.play_state = True
            print '#play'
        print retval

#        result = commands.getstatusoutput('mpc')
#        line_list = retval[1].splitlines()
#        for line in line_list:
#            if self.re_vol.match(line) is None:
#                self.vol_state = False
#                print '### vol False'
#            else:
#                self.vol_state = True
#                print '### vol True'

    def prev(self):
        retval = commands.getoutput('mpc prev')
        print '#prev'
        print retval

    def next(self):
        retval = commands.getoutput('mpc next')
        print '#next'
        print retval

    def stop(self):
        if self.shutdown_timer is 0:
            self.shutdown_timer = 50
            retval = commands.getoutput('mpc stop')
            print '#stop'
            print retval
        else:
            retval = commands.getoutput('shutdown -h now')

    def volup(self):
        if self.vol_state is True:
            retval = commands.getoutput('mpc volume +2')
            print '#vol up'
            print retval

    def voldw(self):
        if self.vol_state is True:
            retval = commands.getoutput('mpc volume -2')
            print '#vol dw'
            print retval


class PlayerStatusFS(object):
    def update(self):
        allLines = open('/proc/asound/card0/pcm0p/sub0/hw_params').read()
        try:
          head, body = allLines.split('rate: ')
        except:
          head, body = "99","99"
        try:
          FsVal, tail = body.split(' (')
        except:
          FsVal = '99'
#        FsVal, BitVal, AnyVal =  Param.split(':')
        self.FsVal = int(FsVal)
#        print self.FsVal
#        if self.FsVal == 384000 :
#                 GPIO.output(PIN_FS0, GPIO.LOW)
#                 GPIO.output(PIN_FS1, GPIO.LOW)
#                 GPIO.output(PIN_FS2, GPIO.LOW)
#                 print self.FsVal
#                 print "384K"
#        else:
        if self.FsVal == 192000 :
                 GPIO.output(PIN_FS0, GPIO.LOW)
                 GPIO.output(PIN_FS1, GPIO.HIGH)
                 GPIO.output(PIN_FS2, GPIO.HIGH)
                 print self.FsVal
                 print "192K"
        else:
          if self.FsVal == 176400 :
                 GPIO.output(PIN_FS0, GPIO.HIGH)
                 GPIO.output(PIN_FS1, GPIO.LOW)
                 GPIO.output(PIN_FS2, GPIO.HIGH)
                 print self.FsVal
                 print "176.4K"
          else:
           if self.FsVal == 96000:
                 GPIO.output(PIN_FS0, GPIO.LOW)
                 GPIO.output(PIN_FS1, GPIO.LOW)
                 GPIO.output(PIN_FS2, GPIO.HIGH)
                 print self.FsVal
                 print "96K"
           else:
            if self.FsVal == 88200 :
                        GPIO.output(PIN_FS0, GPIO.HIGH)
                        GPIO.output(PIN_FS1, GPIO.HIGH)
                        GPIO.output(PIN_FS2, GPIO.LOW)
                        print self.FsVal
                        print "88.2K"
            else:
             if self.FsVal == 48000 :
                        GPIO.output(PIN_FS0, GPIO.LOW)
                        GPIO.output(PIN_FS1, GPIO.HIGH)
                        GPIO.output(PIN_FS2, GPIO.LOW)
                        print self.FsVal
                        print "48K"

             else:
              if self.FsVal == 44100:
                         GPIO.output(PIN_FS0, GPIO.HIGH)
                         GPIO.output(PIN_FS1, GPIO.LOW)
                         GPIO.output(PIN_FS2, GPIO.LOW)
                         print self.FsVal
                         print "44.1K"
              else:
                         print "NoChenged"

class Button(object):
    def __init__(self, pin, func):
        self.pin = pin
        self.old_state = 1
        self.func = func
        GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    def update(self):
        curr_state = GPIO.input(self.pin)
        if self.old_state is 1 and curr_state is 0:
            self.func()
        self.old_state = curr_state

def main():
#    GPIO.cleanup()
    GPIO.setmode(GPIO.BOARD)
    GPIO.setwarnings(False)
    GPIO.setup(PIN_FS0, GPIO.OUT)
    GPIO.setup(PIN_FS1, GPIO.OUT)
    GPIO.setup(PIN_FS2, GPIO.OUT)

    player = Player()

    prev_btn = Button(PIN_PREV_BTN, lambda: player.prev())
    play_btn = Button(PIN_PLAY_BTN, lambda: player.play())
    next_btn = Button(PIN_NEXT_BTN, lambda: player.next())
 #   stop_btn = Button(PIN_STOP_BTN, lambda: player.stop())
 #   voldw_btn = Button(PIN_VOL_DW_BTN, lambda: player.voldw())
 #   volup_btn = Button(PIN_VOL_UP_BTN, lambda: player.volup())
    status_FS = PlayerStatusFS()


    while True:
        prev_btn.update()
        play_btn.update()
        next_btn.update()
#        stop_btn.update()
#        voldw_btn.update()
#        volup_btn.update()
        status_FS.update()
        player.sdtimer()
        time.sleep(0.5)

if __name__ == '__main__':
    with daemon.DaemonContext(pidfile=PIDLockFile('/var/run/mpc_FSLED.pid')):
        main()
        GPIO.cleanup()

/wq


root@volumio:~# chmod 777 /home/volumio/mpc_FSLED.py
root@volumio:~# reboot


◆ タンデム基板の設定

 NB3N2302 FS1 → MSTJP1の22へ

 MSTJP1 11-12、13-14ショート

 JCJP1  7-8、9-10、11-12、13-14ショート

 RaspberryPi GPIOの16,18,22 → JCCN1の14,16,18へ。

  *H26.11.4 赤字部分を追加修正




20 件のコメント:

  1.  もっとスマートな処理したいんですけどFS周波数が判るコマンド見つからないんです。
     mpcは曲名とボリューム値しか返さない。aplayはBusy返して答えてくれない。
     しょうがないからmpdの設定ファイル読み込みました。
     ご存じな方いらしたら情報ください。

    返信削除
    返信
    1. FSを吐き出すコマンドが見つからないんですね。
      procfs ではだめなんですね。

      削除
    2. procfsはvoyageのコマンドでしょうか?Volumioに入ってないです。
      インストールして使えるならそれでもいいのですが。
      mpcかmpdのソースいじらないと駄目かも。

      削除
    3. すみません。私もよくわかってなくて、procfsはLinuxのコマンドです。
      Volumioのコマンドが必要なんですね。

      削除
    4. FS判るファイルみーつけた!
      何とかなりそうです。お楽しみに。

      削除
    5. おお!期待してます!

      削除
    6. できました。
      https://drive.google.com/folderview?id=0B0XnUQ0nJhJWN2Myb0xTX1h2aGM&usp=sharing

      削除
    7. ジャンパプラグはいっぱい刺すことになります。
      JCJP1は88.2~192、MSTJP1は176.4~192

      削除
    8. 早いですね。お疲れ様です。
      Volumio1.4PI_mpc_LED.imgでやってみればいいですか?
      ジャンパプラグは、
      JCJP1 7-8,9-10,11-12,13-14
      MSTJP1 11-12,13-14
      ですね。

      削除
    9. 末尾にMPD.CONFと付いてるファイルは古い奴です。
      Volumio1.4PI_mpc_LED.img展開して、mpc_LED.pyファイルを入れ換えればいいです。
       今日もう少し修正します。
      nanoっていうテキストエディタがviより楽です。ctrl+oで書込み、ctrl+xで終了。
      SSHがTeraTermなら、ALT+Cでコピー、ALT+Vでペーストできます。

      JCJP1 7-8,9-10,11-12,13-14と、21-22
      MSTJP1 11-12,13-14

      削除
    10. わかりました。現状でも全然問題ないので、修正後にやってみます。

      確かにnanoの方が使いやすいんですが、もうviで慣れちゃってるので、ついつい手軽なviを使ってしまいます(笑)。

      削除
    11. と思いましたが、早速やってみました。うまくいきました!
      18日バージョンとの違いは特にないんですよね。

      削除
    12. 更に更新しました。
      変更点は
      ウエイト時間修正 topのプロセス1%以下になりました。
      ポーズ、停止で毎回デフォルトの441にしてたのを、以前の値をキープするように。
      Prev,Play、Nextのボタン位置変更。
      384は出ないからコメントアウト。

      削除
    13. mpc_LED.py を新しく書き換えました。
      ただし、441KhZは音が出ますが、それ以外はだめです。
      ジャンパの設定に変わりはありませんか?

      削除
    14. ジャンパ設定変わらないです。
      FSLED信号が変わるタイミングが変わってますが、影響でたのかな?
      Si5317がロックしないのかもしれません。
      下の方にある time.sleep(0.5)の値を0.1とか減らしてみてください。

      削除
    15. もう一度やり直しました。
      先頭行のcat ./mpc_FSLED.pyを削除したら、すべて上手くいきました。
      ありがとうございます。

      削除
    16. ごめんなさい。
      コピペしくじってました。
      一番上の行のcat mpc_FSLED.py消してください。

      削除
    17. リサンプリングOFFだと16bit441な曲が再生できない場合が有りますね。
      MP3はOKだけど、FLACでNGだったりします。

      BitCLK見たら半分の周波数で出てました。

      削除
    18. うちは全てFLACなので、44.1kHzの場合は16bitはだめで24bitで聴いています。16bitの時BCLKは半分なんですか?!そりゃあvolumioのプログラムミスですね。

      削除
  2. タンデム基板、折角賜ったのですがやはり手におえないような気がします。
    ・・・製作代行して下さる方おられたら嬉しいです。

    返信削除