ラベル Raspberry Pi の投稿を表示しています。 すべての投稿を表示
ラベル Raspberry Pi の投稿を表示しています。 すべての投稿を表示

Raspberry Pi でタッチパネル

Raspberry Pi でタッチパネルを試してみました。

使用した液晶モジュールや接続、設定は以前の記事どおりです。
そのM028C9325TPにはタッチパネルも付いているので、これを使ってみます。
あとRPiはB+でないとGPIOの数が足らないです...(´~`)

ハード的な接続は
を参考に繋いでます。

Linuxカーネルのビルドや準備は
を参考に手元のカーネルソースに追加・設定しビルドしました。

/boot/config.txt を以下のように修正して画面サイズを小さくしています。
framebuffer_width=640
framebuffer_height=480
hdmi_group=2
hdmi_mode=4
タッチパネルの調整も必要なので入力イベントをコンソール上で見れるツールもインストールしておきます。
sudo apt-get -y install xinput evtest
カーネルビルドで参考にしたHPにも書いていますがヘルパーモジュールも必要なので
cd
git clone https://github.com/notro/fbtft_tools.git
cd ~/fbtft_tools/ads7846_device; make && sudo make install
でインストールしています。

ここで一旦タッチパネルを使えるようにして調整~
sudo modprobe ads7846_device gpio_pendown=4
evtest
しかし、調整しようと思ったらXY座標が入れ替わってるっぽいので
sudo modprobe -r ads7846_device
sudo modprobe -r ads7846
でモジュールを削除して、 swap_xyの引数を追加して組み込みしなおします。
sudo modprobe ads7846_device gpio_pendown=4 swap_xy
でも、まだおかしい...Y方向のみ逆になってる...
しかも、入れ替える設定がないっぽい?
仕方ないので、モジュールのソースコードを修正しました。
カーネルソースの linux/drivers/input/touchscreen/ads7846.c の 861 行目辺り
if (Rt) {
    struct input_dev *input = ts->input;

    if (ts->swap_xy)
        swap(x, y);

    y = (y-4095)*-1;

    if (!ts->pendown) {
            input_report_key(input, BTN_TOUCH, 1);
            ts->pendown = true;
            dev_vdbg(&ts->spi->dev, "DOWN\n");
    }

    input_report_abs(input, ABS_X, x);
    input_report_abs(input, ABS_Y, y);
    input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt);

    input_sync(input);
    dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
}                
オレンジ色の1行を追加してY座標を反転させています。
これをコンパイル、組み込みしなおし
evtest
を起動している状態で4隅をタップしてXY座標の最小値、最大値をメモします。
最小値、最大値を引数にして組み込みなおします。
私の環境だと以下のようになりました。
sudo modprobe ads7846_device gpio_pendown=4 swap_xy x_min=523 x_max=3822 y_min=451 y_max=3711
これで調整完了。

今回、動作確認アプリにはJavaFX8を使用しました。
JavaFXだとXWindowなしでUIアプリが作れます。

からARM用JDKをダウンロードして
sudo tar zxvf jdk-8u6-linux-arm-vfp-hflt.gz -C /opt
でインストール。
アプリを640x480の画面サイズで作成し、
/opt/jdk1.8.0_06/bin/java -cp test.jar fx.JavaFXMain
などで実行できます。
JavaFXアプリはRPiに依存することなく、ごく一般的な作り方をすればOKです。

動作確認のため、以下のようにし液晶表示できるようにします。
sudo modprobe fbtft_device name=itdb28 fps=15 rotate=90 gpios=reset:13,dc:5,wr:12,cs:6,db00:14,db01:15,db02:17,db03:27,db04:22,db05:23,db06:24,db07:25
fbcp &
(3行に見えるかもしれませんが、2行です。)

で、実際に動かしてみた動画は以下になります。


JavaFXアプリの起動はさすがに遅いですね (;´д`)
タッチパネルの反応もいまいちな感じです。



Raspberry pi I2S PCM1716でハイレゾ再生

moraでKalafinaのハイレゾ音源(24bit、96kHz)を購入したのでRPiのI2S出力で再生してみようと思います。

PCM1716を使用するにはシステムクロックが必要になるので
Raspberry Pi I2S 出力で外部クロック使用 その2
のようにPLL1707で外部クロックを生成するのですが、当時は16bit、48kHzまでしか想定していないのと768fsを使いたかったせいで、そのままでは使えませんでした。
そんなわけでシンプルにしてみました。


PLL1707は96kHzだと384fsまでしか出せないっぽいので、システムクロックにはPLL1707のSCKO3の384fsを。
RPiの入力に必要なビットクロック64fsはSCKO2の256fsを74AC163で4分周しました。


次にI2Sドライバー側です。過去の記事とほぼ一緒ですが...
以下、GPIOのピン番号はRPi B+用になってます。

sound/soc/bcm/bcm2708-i2s.c
53行目辺り
#include <linux/gpio.h>
#include <linux/delay.h>
539行目辺り
gpio_request_one(26, GPIOF_OUT_INIT_LOW, "MyTest");
if (sampling_rate == 48000 || sampling_rate == 96000) {
  gpio_set_value(26, 0);
} else {
  gpio_set_value(26, 1);
}
gpio_free(26);

gpio_request_one(13, GPIOF_OUT_INIT_LOW, "MyTest");
if (sampling_rate == 96000) {
  gpio_set_value(13, 1);
} else {
  gpio_set_value(13, 0);
}
gpio_free(13);

gpio_request_one(16, GPIOF_OUT_INIT_LOW, "MyTest");
if (data_length == 16) {
  gpio_set_value(16, 0);
} else {
  gpio_set_value(16, 1);
}
gpio_free(16);
GPIO26をPLL1707のFS1に繋いで44.1kHzか48kHzかを設定。
GPIO13をPLL1707のSRに繋いで上記周波数を2倍にするか否かを設定。
GPIO16をPCM1716のIWOに繋いで16bitか24bitかを設定しています。

694行目辺り
struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
uint32_t mask;
int myerr;

switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  myerr = gpio_request_one(12, GPIOF_OUT_INIT_LOW, "MyTest");
  if (myerr == 0) {
    gpio_set_value(12, 1);
    gpio_free(12);
    mdelay(100);
  }

  bcm2708_i2s_start_clock(dev);

  if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
          mask = BCM2708_I2S_RXON;
  else
          mask = BCM2708_I2S_TXON;

  regmap_update_bits(dev->i2s_regmap,
                  BCM2708_I2S_CS_A_REG, mask, mask);
  break;

case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  myerr = gpio_request_one(12, GPIOF_OUT_INIT_LOW, "MyTest");
  if (myerr == 0) {
    gpio_set_value(12, 0);
    gpio_free(12);
    mdelay(100);
  }

  bcm2708_i2s_stop(dev, substream, dai);
  break;
GPIO12をPCM1716のMUTEに繋いでます。

791行目辺り
static struct snd_soc_dai_driver bcm2708_i2s_dai = {
        .name   = "bcm2708-i2s",
        .probe  = bcm2708_i2s_dai_probe,
        .playback = {
                .channels_min = 2,
                .channels_max = 2,
                .rates =        SNDRV_PCM_RATE_8000_192000,
                .formats =      SNDRV_PCM_FMTBIT_S16_LE
                  // : disable for now, it causes white noise with xbmc
                                | SNDRV_PCM_FMTBIT_S24_LE
                                | SNDRV_PCM_FMTBIT_S32_LE
                },
        .capture = {
                .channels_min = 2,
                .channels_max = 2,
                .rates =        SNDRV_PCM_RATE_8000_192000,
                .formats =      SNDRV_PCM_FMTBIT_S16_LE
                                | SNDRV_PCM_FMTBIT_S24_LE
                                | SNDRV_PCM_FMTBIT_S32_LE
                },
        .ops = &bcm2708_i2s_dai_ops,
        .symmetric_rates = 1
};
24bitの所がコメントアウトされていたので外しました。しかし、最新のソースコードだと元々上記のようになってますね。

sound/soc/codecs/pcm1794a.c
24行目辺り
static struct snd_soc_dai_driver pcm1794a_dai = {
        .name = "pcm1794a-hifi",
        .playback = {
                .channels_min = 2,
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_8000_192000,
                .formats = SNDRV_PCM_FMTBIT_S16_LE |
                           SNDRV_PCM_FMTBIT_S24_LE |
                           SNDRV_PCM_FMTBIT_S32_LE
        },
};
一応、SNDRV_PCM_FMTBIT_S32_LEを追加。

sound/soc/bcm/rpi-dac.c
45行目辺り
static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = {
{
        .name           = "HifiBerry Mini",
        .stream_name    = "HifiBerry Mini HiFi",
        .cpu_dai_name   = "bcm2708-i2s.0",
        .codec_dai_name = "pcm1794a-hifi",
        .platform_name  = "bcm2708-i2s.0",
        .codec_name     = "pcm1794a-codec",
        .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
                                //SND_SOC_DAIFMT_CBS_CFS,
                                SND_SOC_DAIFMT_CBM_CFS,
        .ops            = &snd_rpi_rpi_dac_ops,
        .init           = snd_rpi_rpi_dac_init,
},
};
外部クロックを使うように設定しています。

あとはドライバーをコンパイルして適当な場所にコピーして組み込めばOK。
sudo insmod snd-soc-bcm2708-i2s.ko
sudo insmod snd-soc-pcm1794a.ko
sudo insmod snd-soc-rpi-dac.ko

MPDで再生してみるとみごと鳴ってくれました。ヽ(´▽`)ノ




Raspberry Pi B+ 到着 & I2S出力確認

Raspberry Pi B+ が届きました。
しかし、P5がなくなってI2Sが使えるか謎でなんですよね~(´~`)
でも、公式フォーラムによると使えるとのことで試してみました。

sudo rpi-update

でファームウェア更新。

カーネルソースコードもってきてコンパイル。

bcm2708-i2s.c を以下のように赤字部分を修正。
static void bcm2708_i2s_setup_gpio(void)
{
        /*
         * This is the common way to handle the GPIO pins for
         * the Raspberry Pi.
         * TODO Better way would be to handle
         * this in the device tree!
         */
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

        unsigned int *gpio;
        int pin;
        gpio = ioremap(GPIO_BASE, SZ_16K);

        /* SPI is on GPIO 7..11 */
        for (pin = 18; pin <= 21; pin++) {
                INP_GPIO(pin);          /* set mode to GPIO input first */
                SET_GPIO_ALT(pin, 0);   /* set mode to ALT 0 */
        }

#undef INP_GPIO
#undef SET_GPIO_ALT
}

でもって、このドライバーを組み込み、
http://elinux.org/RPi_BCM2835_GPIOs
を見つつ GPIO18、19、21 をDACに繋げば今までと同じように使えました。

/etc/modules に bcm2708_dmaengine も追加する必要あり。







Raspberry Pi に液晶(LCD)を繋いでみました

Raspberry Pi に液晶(LCD)を繋いでみました。
使用したのは Aitendo の M028C9325TP です。


参考HPは以下の通り。
https://github.com/notro/fbtft/wiki
http://www.raspberrypirobot.com/tft-2-8-lcd-raspberrypi-240x320-ili9325c-touch-screen-display-monitor/
http://www.myu.ac.jp/~xkozima/lab/raspTutorial3.html
http://www7b.biglobe.ne.jp/~nobosan_flute/lab_theme31.htm


まずは M028C9325TP を8bitモードにしなくてはなりませんが、
参考HPによるとAitendoのHPの説明が間違っています!
実際、動作しなかったしね...(;´д⊂)

ガバッ!っと液晶をはがして、緑丸で囲ったR2の抵抗をはがして、R1をショートさせる必要があります。
 

あとは
https://github.com/notro/fbtft/wiki/LCD-Modules#itdb02-28
のParallel databusのように繋いでおきます。
(今回はタッチパネルは使用しません)

次に
https://github.com/notro/fbtft/wiki
からSDカードイメージ(2014-01-07-wheezy-raspbian-2014-03-12-fbtft-master-firmware.zip)をダウンロードして起動~!
以下のコマンドで、ドライバをインストール。
sudo modprobe fbtft_device name=itdb28 gpios=reset:17,dc:3,wr:2,cs:27,db00:9,db01:11,db02:18,db03:23,db04:24,db05:25,db06:8,db07:7,led:4 rotate=90
配線間違っていなければ、以下のように表示されると思います。






正面だと白飛びが激しいですね (;´д`)


ちょっと角度をつけると、いい感じです。

動画の再生は fbcp と omxplayer を使えばハードウェア支援ありで再生可能です。
でもLCD自体が10~20fpsみたいなので、少々カクカクですがね~(´~`)
あと、4:3に縮小されるようなので、
omxplayer --win "0 150 1704 870" bbb.mp4
のように横長表示させてあげればLCD上では丁度いいサイズになってくれます。



Raspberry Pi i2s出力とPCM1716でノイズ対策

raspbian だと標準で I2S 出力できるようになりましたが、
手元の PCM1716 を普通に繋いで MPD で再生すると
以下のケースでノイズが出てしまいます。

・再生開始時
・停止時
・シーク時
・音楽フォーマット変更時(16bit<=>24bit、44.1kHz <=> 48kHz など)

いくつか試した結果、外部クロックにしてドライバ内で設定が変わるたびに PCM1716 をミュートして0.1秒のウェイトを入れると、いい感じになりました。ヽ(´▽`)ノ
今まで出ていたポップノイズみたいなのが聞こえなくなってます。
以下、その改良内容です。

クロスコンパイルしたカーネルにRPi上でコンパイルしたドライバを組み込もうとすると、
ハングアップしちゃいます。
前はうまくいってたのになぁ~(;´д⊂)
しかたないのでRPi上でカーネル、ドライバをコンパイル!

https://github.com/raspberrypi/linux
から branch rpi-3.10.y を選択してダウンロード。

いざ、コンパイルしようとすると bc がないと言われちゃいます。
ので、
sudo apt-get install bc
でインストール。
でもってコンパイル!
5~6時間放置!!

コンパイルしたカーネル&ドライバでI2S出力できることを確認してから改良していきます。
赤文字が追加緑文字が更新です。

rpi-dac.c
53行目辺り
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
             //SND_SOC_DAIFMT_CBS_CFS,
             SND_SOC_DAIFMT_CBM_CFS,
これで外部クロックを使えるようになります。

bcm2708-i2s.c
41行目辺り
#include <linux/gpio.h>
#include <linux/delay.h>
を追加。

462行目辺り bcm2708_i2s_hw_params() 内
switch (params_channels(params)) {
case 2:
    format = BCM2708_I2S_CH1(format) | BCM2708_I2S_CH2(format);
    format |= BCM2708_I2S_CH1(BCM2708_I2S_CHPOS(ch1pos));
    format |= BCM2708_I2S_CH2(BCM2708_I2S_CHPOS(ch2pos));
    break;
default:
    return -EINVAL;
}

int myerr = gpio_request_one(4, GPIOF_OUT_INIT_LOW, "MyTest");
if (myerr == 0) {
  if (sampling_rate == 48000) {
  gpio_set_value(4, 0);
  } else {
  gpio_set_value(4, 1);
  }
  gpio_free(4);
}

myerr = gpio_request_one(8, GPIOF_OUT_INIT_LOW, "MyTest");
if (myerr == 0) {
  if (data_length == 16) {
  gpio_set_value(8, 0);
  } else {
  gpio_set_value(8, 1);
  }
  gpio_free(8);
}
フォーマットに応じてPCM1716とPLL1707の設定を変更しています。
GPIO4はPLL1707のFS1 (PIN 5)、GPIO8はPCM1716のIW0 (PIN 23) に繋いでいます。
PCM1716のフォーマット選択はしなくても音鳴ってたけど、ついでなので制御するようにしました。

645行目辺り bcm2708_i2s_trigger() 内
int myerr;

switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
    myerr = gpio_request_one(7, GPIOF_OUT_INIT_LOW, "MyTest");
    if (myerr == 0) {
      gpio_set_value(7, 1);
      gpio_free(7);
      mdelay(100);
    }

    bcm2708_i2s_start_clock(dev);

    if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
        mask = BCM2708_I2S_RXON;
    else
        mask = BCM2708_I2S_TXON;

    regmap_update_bits(dev->i2s_regmap,
            BCM2708_I2S_CS_A_REG, mask, mask);
    break;

case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
    myerr = gpio_request_one(7, GPIOF_OUT_INIT_LOW, "MyTest");
    if (myerr == 0) {
      gpio_set_value(7, 0);
          gpio_free(7);
      mdelay(100);
    }

    bcm2708_i2s_stop(dev, substream, dai);
    break;
default:
    return -EINVAL;
}
停止や再開の時にPCM1716をミュートにして0.1秒ウェイトしています。
GPIO7をPCM1716のMUTE (PIN 25)に繋いでいます。

以上の修正をしたらドライバをコンパイルして組み込めばOK~

MPDクライアントでどんな操作してもポップノイズみたいなのが出なくなりました。ヽ(´▽`)ノ





Raspberry Pi 最近のI2S出力事情

最近のRPiは標準でI2S出力ができるようですね。
一昔前はドライバのコンパイルが必要だったのに~(;´д⊂)

どんな感じなのか 2014-01-07-wheezy-raspbian で試してみました。
インストール直後は使えないのかな?
/etc/modules
を以下のように編集すると使えるようになりました。
赤字の部分を追加しています。
snd-bcm2835
snd_soc_bcm2708_i2s  
bcm2708_dmaengine  
snd-soc-pcm1794a   
snd_soc_rpi_dac
以前と同じようにPCM1716を繋いで鳴らしてみました。
システムクロックはBCKをICS570を使って4倍にしてます。


普通に使えてます。
随分手軽に使えるようになったのね~(´∀`)






Raspberry Pi で XBMC

RPiを購入したころにRaspBMC(RPi用XBMC)を使ってみましたが、
当時はあまり有効な使い方を思いつきませんでした。

しか~し!最近、知ったのですがRaspBMCってリモートコントロールできるんですね!(;゜ロ゜)
リモートコントロールできるなら使い道がありそうです。

でも、個人的に便利に思う機能はデフォルトOFFになっていました。
以下のようにAirplay、UPnPの機能をONにできます。



AirplayをONにするとiTunesやiPodから出力先をRaspBMCにすることができます。
でも残念なことにRaspBMCでAirplayは少々不安定なようです。

また、UPnP関係の機能をONにするとRaspBMCをDMRにすることができるようです。
Windows8から「Play To」で動画や音楽ファイルをRaspBMCで再生させることができます。




MPEG2ライセンスを購入してRaspBMCに設定しておけば、TSファイルもスムーズに再生可能でした。しかし、途中で解像度が変わるような物はダメですね。解像度が変わるタイミングで映像が止まってしまいます。こういうファイルはTsSplitterなどで切り出しておく必要がありますね。




Raspberry Pi で音楽ファイルのリモート再生 Windows8[Play To]編

Windows8でwavファイルを右クリックすると「Play To」という見慣れないメニューがあるのに気付きました。
マウスカーソルを合わせてみるとAVアンプの名前が表示されるではないですか!(;゜ロ゜)
これはリモート再生の類かなと思って調べてみると、やはりそのようです。
どうもDMRに対応したDLNA機器をネットワークに繋いでると表示されるみたい。

もしや...RaspberryPi(以下RPi)使えばDLNA非対応な自宅TVDMRのようにできちゃうかも!

ってことで、まずは簡単に実現可能な音楽ファイルの再生をやってみました。

以下のHPの手順で GMediaRenderer をインストールします。

これだけでAndroidアプリのUPnPlayなどで、Andtoid内とかDLNAサーバ上の音楽ファイルをRPiでリモート再生できます。

Windows上の「Play To」を使えるようにするには以下のHPの通りにします。

そうすると以下の画像のように「Play To」からRPiを選択できちゃいます。


ただ、少々問題がありますね。
 ・曲の頭1秒ほど再生されない場合がある。(1曲目は100%再現!?)
 ・WindowsMediaPlayerのプレイリストの再生はうまくいかない。
 ・たまに不安定になる。

上記以外は特に問題なさそうです。wav、Apple Losseless、iTunes購入曲、AmazonMP3購入曲なども再生できました。



Raspberry Piで動画再生 VLC編

omxplayerで久々にMPEG2-TSを再生しようとしたら再生できない!
GPUメモリが足りなかったようです。
前は64MBで再生できたような気がするけど128MBに設定したら再生できるようになりました。

あと、いつのまにかVLCでもハードウェア支援が受けられるようになっていたんですね。
http://intensecode.blogspot.jp/2013/10/tutorial-vlc-with-hardware-acceleration.html
GPUに128MB確保した旧256MB版RPiだとメモリが足らずコンパイルできなかったので
新512MB版RPiを使用したほうがいいです。
コンパイルには6時間くらいかかります。寝ている間にコンパイルしておくのがいいかと思います。

このVLC、XWindow上でもコンソール上でも実行できます。

実際にMPEG2-TSを再生してみましたがomxplayerに比べるとコマ落ちしちゃってます。
アニメなら許容範囲だと思いますが、実写だと気になるレベルかもしれません。




RaspberryPi SDカードイメージのミラー

久しぶりにRaspberryPiのSDカードイメージを公式(http://www.raspberrypi.org/downloads)から
ダウンロードしょうとしたらものすごく遅い!(>_<)

前は我慢できないほど遅くなかったはずなんだが...

ミラーないかな~と思って探してたら...あったんですね!(゜∇゜)
http://ftp-admin.blogspot.jp/2013/02/raspberry-pisd.html
30分ほどでダウンロード完了しました。




Raspberry Pi I2S 出力で外部クロック使用 その2

前回、Raspberry Pi I2S 出力で外部クロックを使用できるようにしましたが
そのままでは44.1kHzの音楽ファイルしか正しく再生出来ません。
ちなみに48kHzな音楽ファイルを再生すると少しスロー再生になります。(´~`)

PLL1707のFS1LOWHIGHにしてやれば 48kHz44.1kHz を切り替えられるので、
i2sドライバ内でGPIOを操作してやればうまくいきそうな感じがしますよねぇ~

MPDの場合、音楽ファイルのフォーマットが変われば bcm2708-i2s.c の bcm2708_i2s_hw_params()関数が呼ばれることがわかっているので、ここにGPIO操作の処理を追加してやります。

bcm2708-i2s.c の適当な場所に
#include <linux/gpio.h>
を追加。
bcm2708-i2s.c の444行目辺りに以下のコードを追加します。
int myerr = gpio_request_one(4, GPIOF_OUT_INIT_LOW, "MyTest");
if (myerr == 0) {
  if (sampling_rate == 48000) {
    gpio_set_value(4, 0);
  } else {
    gpio_set_value(4, 1);
  }
  gpio_free(4);
}
これで音楽ファイルのフォーマットが48kHzの時はGPIO4LOWに、44.1kHzの時はHIGHになります。

あとはRPiのGPIO4とPLL1707のFS1を繋いでやればOKなのですが...
直接繋ぐと私の環境ではノイズだらけに...
配線を遠回りさせてやるとノイズが消えました...
素人にはわけわかめ謎すぎです( ̄~ ̄;)

でもまぁ、これでMPD48kHz44.1kHz混在プレイリストでも問題なく再生できるようになりました。ヽ( ´ー`)ノ
もちろん外部クロックにしているので曲間(フォーマット切り替わり時)でポップノイズみたいなのは出ません。




どうもPLL1707の出力にバッファを付ければ配線を遠回りさせなくてもノイズがでないもよう。
36MHzくらい出てるはずなので74AC14を付けてみました。
PIN9のGNDもつなぎ忘れてた~(;´д`)





Raspberry Pi I2S 出力で外部クロック使用

システムクロックの線を抜き差しするとポップノイズっぽいのが聞こえたので、
外部クロックを使うようにすればポップノイズが消えるかも知れないと思って試してみました。

結論から言うと、今までの低い音のポップノイズはしなくなったけど、
代わりに高い音のポップノイズが出るようになっただけでした...(´・ω・`)

外部クロックを使用するには、またドライバのソースをいじるのですが、
念のために今までの修正を全て元に戻しておきます。
で、/usr/src/3.8.10+/sound/soc/bcm2708/rpi-tda1541a.c の 46行目を以下のようにします。
        .name           = "TDA1541A",
        .stream_name    = "TDA1541A HiFi",
        .cpu_dai_name   = "bcm2708-i2s.0",
        .codec_dai_name = "tda1541a-hifi",
        .platform_name  = "bcm2708-pcm-audio.0",
        .codec_name     = "tda1541a-codec",
        .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
                             // SND_SOC_DAIFMT_CBS_CFS,
                        SND_SOC_DAIFMT_CBM_CFS,

        .ops            = &snd_rpi_tda1541a_ops,
        .init           = snd_rpi_tda1541a_init,
これで64fsなビットクロックを外部入力することが出来ます。
でもって、何かしらの外部クロックを接続すればOKです。
今回は PLL1707 を繋いでみました。


丁度いいピッチ変換基板が売られていなくて、かなりごちゃごちゃしちゃってます。( ̄~ ̄;)
PLL1707の768fs出力をDACのシステムクロックへ入力、
PLL1707の768fs出力を12分周した64fsをRPiとDACのビットクロックに入力しています。
分周には
http://homepage2.nifty.com/y-daisan/html/B100529-2.html
を元に 74AC163 と 74HC10 を使用しています。

768fsとなると36MHz以上になります。
74HCシリーズの動作速度は30MHzくらいまでらしいのでカウンターの74163には74AC163を使用しています。
7410のほうは最高でも768fsの半分の周波数なので、74HC10でも大丈夫と思われます。

電子工作を始めるまではデジタル回路にノイズなんてないだろう~
と思っていましたがノイズでまくるんですね(>_<)
今回もノイズに苦しめられましたが、なんとかなってよかった~(;´д`)
検証はしてませんが 74AC163 と 74HC10 にパスコン付けたらノイズが消えた...気がします。




Raspberry Pi I2S 出力 24bit 48kHz 再生

公式フォーラムではこのドライバをちょこっと修正で192kHzでも再生出来た~って書き込みがありますね。

じゃ~試してみよう!...と、思っても192kHzなデータは持ってません。
そんなわけで24bit 48kHzを試してみました。
PCM1716を使えるようにしたのもこれを試したかったからなのよね~(´―`)

ちなみに何もドライバを修正せずに48kHzの音楽を鳴らしてみるとハングアップしてしまいます。
電源をOFFにするしかない状態です。( ̄~ ̄;)

修正前にちょっと準備します。
クロスコンパイル環境でコンパイルしてもいいのですが、何度も「コンパイル > RPiに転送」は面倒くさいので RPi 上でドライバだけコンパイル出来るようにします。
https://github.com/koalo/linux
からソースコードの linux-rpi-3.8.y-asocdev.zip をダウンロードし、/usr/src に展開します。
ディレクトリ名は 3.8.10+ とでもしておきます。
既にクロスコンパイル環境で作成したカーネル 3.8.10+ で起動しているものとします。
cd /usr/src/3.8.10+
zcat /proc/config.gz > .config
make oldconfig
make modules_prepare
クロスコンパイル環境から Module.symvers を RPi の /usr/src/3.8.10+ へコピー
これでドライバのコンパイル準備完了です。

まずは /usr/src/3.8.10+/sound/soc/bcm2708/bcm2708-i2s.c 420行目辺りを修正します。
今回はIISフォーマット入力可能なDACを使用するため、以前紹介した標準フォーマット出力の修正は行いません。
//      if (bcm2708_clk_freq[clk_src] % target_frequency == 0
//                      && bit_master && frame_master) {
//              divi = bcm2708_clk_freq[clk_src]/target_frequency;
//              divf = 0;
//      } else {
                uint64_t dividend;

                /*
                 * Overwrite half frame length, because the
                 * above trick is not needed.
                 * This is fixed, because a bit clock of 64*fs
                 * seems to be what most codecs want.
                 * Is it necessary to have this dynamic?
                 */
                half_frame = 32;
                target_frequency = sampling_rate*half_frame*2;

                clk_src = BCM2708_CLK_SRC_PLLD;
                mash = BCM2708_CLK_MASH_1;

                dividend = bcm2708_clk_freq[clk_src];
                dividend *= 1024;
                do_div(dividend, target_frequency);
                divi = dividend / 1024;
                divf = dividend % 1024;
  if (sampling_rate == 48000) {
     divi = 162;
     divf = 3000;
  }
//      }
どうやら48kHzの場合、if文のほうに流れて後の処理でハングアップするようです。
ので、コメントアウトしちゃいます。
でもって、diviとdivfで出力周波数を設定するようです。else内の計算だと48.1kHzになっちゃうので48kHzデータの場合は自前で値を代入しちゃってます。上記の数値でだいたい48.008kHzになります。
で、コンパイル!
cd /usr/src/3.8.10+/sound/soc/bcm2708
make -C /usr/src/3.8.10+ M=/usr/src/3.8.10+/sound/soc/bcm2708 modules
次に /usr/src/3.8.10+/sound/soc/codecs/tda1541a.c 24行目を修正します。
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
32bitのデータを受け付けるようにします。
この修正をしない場合は mplayer かドライバが16bitに変換するようです。
あと24bitを表す定数は存在するけど意味ないっぽいです。
mplayerだと24bitの音楽ファイルでも32bitとして扱っているみたいです。この辺はよくわかりません~(;´д`)
で、コンパイル!
cd /usr/src/3.8.10+/sound/soc/codecs
make -C /usr/src/3.8.10+ M=/usr/src/3.8.10+/sound/soc/codecs modules
でもって、ドライバを登録します。
cd /usr/src/3.8.10+/sound/soc/bcm2708
sudo insmod snd-soc-bcm2708-i2s.ko
sudo insmod snd-soc-rpi-tda1541a.ko
sudo insmod ../codecs/snd-soc-tda1541a.ko
あとはmplayerなどで再生すればOK!ヽ( ´ー`)ノ
もちろん、DAC側でIISを入力出来るようにしておく必要があります。PCM1716だとIIS、IW0ピンをHにします。


上がデータ、下がLRクロックです。24bitで出力されているようですね。


さて、16bit 44.1kHz と 24bit 48kHzの違いですが...あんまり変わらない...( ̄~ ̄;)
市販のAVアンプだと結構変わった印象があったので、ちょっと期待していたのですが残念ですなぁ。

MPDで使用する場合は /etc/mpd.conf を以下のように修正しておきましょう。
audio_output {
        type            "alsa"
        name            "ALSA I2S Device"
        device          "hw:1,0"        # optional
#        format          "44100:16:2"    # optional
}
formatはコメントアウトしておかないと常に 44.1kHz 16bit で出力されるようです。


あと、ついでなのでOPアンプを NJM2114DD から OPA2604 に変えました。
OPアンプの交換は変化がわかりやすいですね~
NJM2114DDは平べったい音で眠気を誘う音でしたが、OPA2604はメリハリがあり、聴いてて楽しい音です。
ここでフト思ったのですが、眠気を誘うアンプって以外と需要あったりしないのだろうか?
そんな時はNJM2114DDのような音をお試しあれ~(´―`)




RaspberryPiでMPD

RaspberryPi I2S出力 + PCM1716 + mplayer だとリスト再生時の最初と最後と曲間のポップノイズがかな~りひどいです。
ということで、ギャップレス再生に対応しているらしいMPDを試してみることにしました。

ネットの情報を元にインストール('~')
インストールは簡単ですね。
sudo apt-get install mpd mpc
でもって /etc/mpd.conf を編集~
#bind_to_address                "localhost"
mixer_type "disabled"

audio_output {
        type            "alsa"
        name            "ALSA I2S Device"
        device          "hw:1,0"        # optional
        format          "44100:16:2"    # optional
}
緑色は編集、赤色は追加です。

ここで念のためRPiを再起動

音楽ファイルはコピー面倒なので、WindowsマシンのiTunesフォルダをマウントして /var/lib/mpd/music/ にシンボリックリンクを作成しました。
mpc update
とすれば音楽ファイルリストを更新してくれます。

これで再生準備完了~
ただ、このMPDはサーバープログラムなので、再生指示は別のクライアントアプリから行う必要があります。
とりあえずWindows用のアプリ Cantata を使ってみました。



出力先はI2Sの方にして、さっそく再生!

普通に再生されて、曲間のポップノイズもでなくなりました。
ただ、プレイリストの最初と最後はポップノイズでちゃいますね~(´~`)
どうにかならないものか...(>_<)



RaspberryPiにPCM1716をつないでみた

以前 RaspberryPi の I2S 出力に PCM1716 を繋ごうとしたけど、システムクロック出力がなくて繋げませんでした。

しかし、世の中には便利なICがあるんですね。ネットを徘徊していると ICS570 という周波数をn倍してくれるICがあるそうです。
これを使えば PCM1716 も繋げそうですね。
ただリアル店舗では売られてないのかな?
でも、RSコンポーネンツなどで注文できます。今回は3.3V用のICS570Bを注文しました。

届いたのがこちら。



小さめのICなのでピッチ変換基板に乗せています。

PCM1716を繋ぐには一例として44.1kHzの256倍のクロック信号が必要です。
RPiのI2S出力は片チャンネル32ビットなので、ビットクロックが既に64倍になっています。
ってことはこれを4倍すれば256倍になることになります。

実際にICS570を動かしてオシロで信号を見てみると...



ほぼ4倍されてますね~(´~`)
黄色の線がRPiのビットクロック。青色の線がICS570の出力。

さっそくPCM1716を繋いでみました。
、またまたノイズに悩まされることに...



結論をいいますと、矢印で示した白い線を追加すればノイズが消えてくれました。
GNDってコの字型でも繋がってればOKと思っていたのですが、だめなんですかね。
白い線を足すことでGNDが口の字に繋がることになります。
こんなことでノイズが出たり消えたりするなんて、素人には難しすぎるわ~(>_<)

RPiから直接PCM1716に繋ぐとノイズがでてたので、間に74HC04を挟んでいます。
 

ちょこっとギュウギュウ詰めにしてみました。

音に関しては...とりあえず鳴っています。
前にCS8416と繋いだ時はLPFとかなしでもクリアに聞こえていた気がしたのですが、今回はLPFないとノイズだらけ...
こういうもんなんですかね~( ̄~ ̄;)



RaspberryPi I2S mplayerディレクトリ再生

以前のhttp://abc002.blogspot.jp/2013/05/raspberry-pi-alsa-i2s.html
で紹介したI2S経由の再生を楽しんでいるのですが、
たまに音飛びするのが気になるようになってきた~(;´д`)

オーバークロックのせいかな~と思ってオフにすると、音飛びがさらにひどくなったぁ~(>_<)
ってことはCPUパワー使わないと思っていたけど結構使うのかな?
なら単純にデコード間に合ってない時があるのかも...ってことで
オーバークロックをオンにして、mplayerのオプションに -cache 1500 を付けてみました。
今のところ音飛びしてないですが、しばらく様子見ですね~。

あと、SDカードにいちいち音楽ファイルをコピーするのが面倒くさくなってきました。( ̄~ ̄;)
ってことでWindows共有フォルダをマウントしてしまいましょう。
sudo mount -t cifs -o username=XXXXX //192.168.XXX.XXX/itunes /mnt
という感じでマウントできます。

しかし、今度はいちいちプレイリストを作るのがめんどくさくなってきました...(;´д`)
mplayerでディレクトリ再生ってどうやってやるんでしょうね~
さっそくGoogle先生にきいてみると。
mplayer -quiet -ao alsa:device=hw=1.0 -cache 1500 -playlist <(find $PWD -type f)
とすればいいとのこと。
しかし、これはBシェル系でないと動かないっぽい。
私は普段Cシェルを使っています。こんな時はシェルスクリプトにすればいいですね。
適当なファイル名を付けて以下のような内容だけでOK。
#!/bin/bash
mplayer -quiet -ao alsa:device=hw=1.0 -cache 1500 -playlist <(find "$PWD" -type f)
たぶん、スペースのあるディレクトリでもいけるかと思います。
再生したいファイルのあるディレクトリに移動してシェルスクリプト起動するだけで
ディレクトリ内のファイルを連続再生してくれます。




Raspberry Pi で NFC

Raspberry Pi でNFCをやってみようと思い、ebayでモジュールを購入するも不良品か、使い方が悪いのか、うまく動かず。

そこでSONYの RC-S360 を購入~

(GPIOに刺さっているケーブルは今回関係ありません。)
(今はRC-S360手に入りにくい!? 同じように使えるかわからないけど、楽天Edyリーダーが中身はRC-S360という書き込みがレヴューにありますねぇ)

ちなみにやることはRaspberryPi特有な手順ではなく、Linuxなら同じようにできるようです。
まずは準備~(´∀`)
sudo apt-get install libusb-dev
sudo apt-get install libpcsclite-dev
wget http://libnfc.googlecode.com/files/libnfc-1.7.0-rc7.tar.gz
tar zxvf filename
cd libnfc-1.7.0-rc7
./configure --with-drivers=pn53x_usb
make
sudo make install
sudo ldconfig
makeは6分ほどで完了します。
今回はUSBのリーダーを使うので configure の引数でUSBのドライバだけ有効にしています。

さっそくサンプル実行するもエラー!( ̄~ ̄;)

最近のカーネルでは標準の?ドライバがロードされてしまうみたい。
lsmodすると確かにロードされている。
/etc/modprobe.d/raspi-blacklist.conf に以下の2行を追加してロードされないようにします。
blacklist pn533
blacklist nfc
でもって再起動

プログラムを動かして以下のようなエラーが出る場合はsudoを付けるといいです。
error   libnfc.driver.pn53x_usb Unable to set USB configuration (Operation not permitted)
nfc_test: ERROR: Unable to open NFC device.
が!
ここからが長かった...(;´д`)
NFCってタグがあって、リーダーがあってプログラムがあればすんなり動くものだと思っていたらそんなことなかった...

まずは libnfc がサポートしているリーダーを使わなければなりません。
これはあらかじめ調べて RC-S360 を購入したので問題なし。

はまったのはタグの方で、いろんな種類があって種類ごとにプログラム側で読み方を変えなくてはならないのです。
最初は MIFARE Standard (Classic) というタグ(カード)で試してたんだけど認証がうまくいかず、がんばっても無理でした。(;´д⊂)
で、Androidで手持ちのタグの情報をみていると1つだけ種類が違うのに気付きました。写真の左2つが MIFARE Standard (Classic) で一番右のが MIFARE UltraLight といタグになります。
このタグは アキバ大好き!祭り で購入した物です。
MIFARE UltraLight は認証処理が必要なく、単純に読み書きする処理だけでいいのです。



今までの苦労はなんだったんだ~ヽ( ̄皿 ̄)ノ  ってくらい MIFARE UltraLight のタグだとあっさり情報の読み取りに成功しました。
しかし、問題がもう一つあります。
このタグは1枚しか持ってないので何枚か購入しようと思ったのですが、どこにも売ってない感じです。通販で1カ所あったくらいかな。
で、Google先生に聞いてみると、今はUltraLightの容量を少し増やした NTAG203 が主流のようです。記録可能容量は144バイト。



これなら八重洲のNFCショップや秋葉原のショップ、Amazonなどで購入可能です。



ということで、このタグにAndroidタブレットでNDEFのPlainTextを書き込んで読み込んでみました。


4バイトずつ読み込み先アドレスを変えつつ36回読み込むと144バイト読めます。
それを文字列として結合し、最後の行で表示しています。
「Raspberry Pi Test2」と表示されているので、うまく読み込めてますね。
前後に変なデータが付いてますがこれはおそらくNDEFのヘッダーなどと思われます。

サンプルプログラムは折りたたんでおきます。

Raspberry Pi でCD-ROMドライブ経由CD再生


CD再生自体は去年やったこととほぼ同じ事ですが、CD再生でも ALSA I2S の方へ出力されるのか試してみました。

まずは古いIDEなCD-ROMドライブにIDE-USB変換を付けてRaspberryPiのUSBに繋ぎました。
Google先生によると、mplayerでCD再生は以下のようにするといいとのこと。
mplayer -quiet -ao alsa:device=hw=1.0 -cdrom-device /dev/cdrom cdda://
試してみると、CD-ROMドライブが爆音回転しますが問題なく再生できますね。
I2Sのほうへ無事出力されていました。

ただこの高速回転の爆音では音楽に集中できません。
何か回転速度を制限するツールはないのかとGoogle先生に聞いてみると eject というコマンドがいいとのこと。

早速インストールしてみましょう。
sudo apt-get install eject
でインストール出来ます。
最大速度を1倍にする場合には
eject -x 1
とすれば回転速度を制限できます。
このコマンドの後にmplayerコマンドを使用すると静かにCD再生することができました。ヽ( ´ー`)ノ

ちなみにこのejectコマンドでトレイのオープン、クローズもできちゃいます。
 オープン eject
 クローズ eject -t


今回使用したCD-ROMドライブは PLEXTOR CD-R PX-320A なのですが、手持ちの他のドライブでは回転数最大でもデータ読み込みが再生に追いつかず、音飛びしまくりでした。相性とかあるのかもしれませんね~ ( ̄~ ̄;)




Big Raspberry JAM TOKYO 2013

5月25日にBig Raspberry JAM TOKYO 2013が開催されれますね。


申し込みはこちら。 http://atnd.org/event/E0015063/

これを知ったころは申し込もうにも定員いっぱいで申し込めませんでしたが、
今日ちょこちょこ申し込みページ見てたら119/120になってたので申し込んでみました。
申し込み後でもキャンセル出来るようで空きができる場合があるようです。
この記事書いてる時もまた119/120になってました。


そんな今日5/21は22日発売のCDやDVDが届き始める日ですね。
うちにもRSコンポーネンツで注文したICとともに届いてました。(´∀`)
明日辺りにはRaspberryPi用カメラモジュールも届く予定です。






RaspberryPiのmplayerでAACオーディオファイル再生

前回の記事 http://abc002.blogspot.jp/2013/05/raspberry-pi-alsa-i2s.html
で紹介したように RaspberryPi の I2S 出力経由でオーディオ再生が出来るようになりました。

ここまで出来るようになると、次は手持ちの音楽ファイルをいろいろ再生したくなりますね。
mp3とwavはmpg321やaplayで再生できましたがAACとかはどうするのでしょう?(´~`)
Google先生に聞いてみるとmplayerなどを使うといいとのこと...

さっそくインストールして実行してみるも 「Illegal instruction」とでて起動しない!(;´д`)
いろいろいじくっててライブラリとかが変になっているんでしょうね。
ので、SDカードイメージを書き込むところからやり直しました。

SDカードイメージを書き込んで、なんやかんや設定するのは省略~
肝心のmplayerインストールは
sudo apt-get install mplayer
のみでOK。
でもってI2Sを使えるようにした linux-image-3.8.10_0.1_armhf.deb をインストールして再起動
debファイルにしてると再インストール時とか楽でいいですな。ヽ( ´ー`)ノ

再起動後、I2S関係のドライバを insmod すれば再生準備完了~
mplayer -quiet -ao alsa:device=hw=1.0 XXXX.m4a
とすればあっさり再生できました。
・m4aな自分でエンコードしたAAC
・m4aなALAC(Apple Lossless Audio Codec)
・m4aなiTunes Store購入曲
・mp3
・wav
どれも問題なく再生できますね。
CPU負荷もたいしたことないようです。高負荷時は1GHzになるように設定していますが再生中は700MHzのままでした。

プレイリストも利用できます。
適当なファイル(XXXXX.listなど)にファイル名を列挙して、
mplayer -quiet -ao alsa:device=hw=1.0 -playlist XXXXX.list
とすればプレイリスト内のファイルを連続で再生してくれます。

mplayerってffmpegを使っているようなので、おそらく大抵のオーディオファイルは再生できるかと思われます。