2018年02月13日

LÖVE (Love2D) を Raspbian Stretch で動かす

 ゲームエンジンの LÖVE (Love2D) なんですが、最新の Raspbian Stretch でうまく動かない問題があった。音を鳴らそうとするとトラブルが起きる。

  • Raspberry Pi1 では、Illegal Instruction で落ちてしまう(たぶん Zero でも)。
  • Raspberry Pi3 では、落ちはしないが、発音がひどく遅れる(たぶん Pi2 でも)。

 Illegal Instruction はダメでしょ。Gdb で動作させて調べてみたところ、libopenal.so の中で落ちていることがわかった。OpenAL が壊れているらしい。試しに、こんなコードで検証してみた(openal.c とする)。

#include <stdlib.h>
#include <stdio.h>
#include <AL/alc.h>
#include <AL/al.h>

int ReadHeaderWav(FILE* fp, int *channel, int* bit, int *size, int* freq) {
  int16_t res16;
  int32_t res32, dataSize, chunkSize;
  int16_t channelCnt, bitParSample, blockSize;
  int32_t samplingRate,byteParSec;	
  int dataPos, i, flag = 0;
  
  fread(&res32, 4, 1, fp);
  if (res32 != 0x46464952) {	/* "RIFF" */
    return 1;	//error 1
  }
  fread(&dataSize, 4, 1, fp);  /*  Data size  */
  
  /*  WAVE header  */
  fread(&res32, 4, 1, fp);
  if (res32 != 0x45564157){	/* "WAVE" */
    return 2;	//error 2
  }
  
  /*  Chunks  */
  while (flag != 3) {
  fread(&res32, 4, 1, fp);
  fread(&chunkSize, 4, 1, fp);
    switch (res32) {
    case 0x20746d66:	/* "fmt " */
      fread(&res16, 2, 1, fp);
      if (res16 != 1) {
        return 4;  /*  Not supported  */
      }
      fread(&channelCnt, 2, 1, fp);
      if (res16 > 2) {
        return 5;  /*  Not stereo nor monoral  */
      }
      fread(&samplingRate, 4, 1, fp);
      fread(&byteParSec, 4, 1, fp);
      fread(&blockSize, 2, 1, fp);
      fread(&bitParSample, 2, 1, fp);
      *channel = (int)channelCnt;
      *bit = (int)bitParSample;
      *freq = samplingRate;
      flag |= 1;
        
      break;
    case 0x61746164:	/* "data" */
      *size = chunkSize;
      dataPos = ftell(fp);
      flag |= 2;
      break;
    }
  }
  fseek(fp, dataPos, SEEK_SET);
  return 0;
}

int main (int argc, char **argv)
{
  ALuint buffer, source;
  FILE *fp;
  int wavChannel, wavBit, wavSize, wavFreq;
  unsigned char *data;
  int i, fmt;
  
  ALCdevice *device;
  ALCcontext *context;
  
  /*  Initialize  */
  device = alcOpenDevice(NULL);
  context = alcCreateContext(device, NULL);
  alcMakeContextCurrent(context);
  
  fp = fopen("bgm.wav","rb");
  if (ReadHeaderWav(fp, &wavChannel, &wavBit, &wavSize, &wavFreq)){
    printf("Format not supported\n");
    return 1;
  }
  data = (unsigned char *)malloc(wavSize);
  fread(data, wavSize, 1, fp);
  fclose(fp);
  
  alGenBuffers(1, &buffer);
  if (wavChannel == 1)
    fmt = (wavBit == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16);
  else
    fmt = (wavBit == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16);
  alBufferData(buffer, fmt, data, wavSize, wavFreq);
  
  alGenSources(1, &source);
  alSourcei(source, AL_BUFFER, buffer);
  for (i = 0; i < 5; i++) {
    fprintf(stderr, "play\n");
    alSourcePlay(source);
    sleep(1);
    alSourceStop(source);
  }
  
  alDeleteBuffers(1, &buffer);
  alDeleteSources(1, &source);
  free(data);
  return 0;
}

 gcc -g -o altest altest.c -lopenal でビルドして、gdb で実行してみた。Pi3 では "play" と表示されてから約 0.6 秒遅れで音が鳴る。Pi1 では、"play" が1回表示された直後に下のエラーで落ちる。

Thread 4 "altest" received signal SIGILL, Illegal instruction.
[Switching to Thread 0xa59ff460 (LWP 593)]
0xb6f3ead4 in ?? () from /usr/lib/arm-linux-gnueabihf/libopenal.so.1

 これは libopenal.so をビルドし直して差し替えるしかないね。ついでに、pulseaudiojack が問題を起こすので、非対応にする。

$ wget http://kcat.strangesoft.net/openal-releases/openal-soft-1.18.2.tar.bz2
$ tar xvjf openal-soft-1.18.2.tar.bz2
$ cd openal-soft-1.18.2/build
$ cmake -DALSOFT_BACKEND_JACK=OFF -DALSOFT_BACKEND_PULSEAUDIO=OFF -DCMAKE_INSTALL_PREFIX=/usr/local/games/love ..
$ sudo mkdir -p /usr/local/games/love; sudo chown pi /usr/local/games/love
$ make && make install

 さっきの altest を試してみる。ちゃんと音が出るようになった。新しく作った libopenal.so をリンクするため、LD_LIBRARY_PATH 環境変数を設定する。

$ LD_LIBRARY_PATH=/usr/local/games/love/lib ./altest

 これに対応した Love2D のビルドスクリプトを作りました。→「LÖVE (Love2D) プログラミング:インストール

posted by toshinagata at 00:12| 日記

2018年02月12日

CCさくらの「おぼろ月夜」

 今週のカードキャプターさくら(いい年したおっさんが毎週リアルタイムで見ている)で、知世ちゃんと秋穂ちゃんが「おぼろ月夜」をデュエットしていた。そのアレンジがよかった。根岸貴幸さん、いい仕事してますね。

 知世ちゃんが楽譜を渡すシーンで、一瞬だけ楽譜が大写しになる。ちゃんと音符が書いてあります。細かい比較はしてないけど、実演と合ってるんじゃないでしょうか。

20180212-1.jpg

 実はこの歌、わりと苦手だった。A→E→D という進行が3回出てくるんだけど、どうもしっくり来ない。

20180212-2.png

 作曲者の岡野貞一さんは、どういう和音進行を想定して書いたんだろうか。Am→G としてしまうと、露骨に連続5度が起きて、すごくマヌケな感じになってしまう。学校の音楽の授業だと、だいたいこういう伴奏をつけられてしまう。これで何度も歌わされるのって、けっこう苦痛ですよ。

20180212-3.png

 根岸さんのアレンジはこうなっている。1回目は Am→G7, 2回目は Am→D9→G9sus4, 3回目は Dm9→G9。

20180212-4.png
20180212-5.png
20180212-6.png

 3回目の2拍オモテに8分休符があるのはどうしてですかね。E が F→E→D の経過音に見えるのを嫌ったのかな。

20180212-7.png

 ちなみに、ピアノ伴奏を受け持ったのはなんと小狼君。これを初見で弾いて、コーラス部の知世ちゃんに「歌いやすかった」と言わせるのって、中学生としては相当の腕前だぞ。いつ練習してるんだろう。

タグ:音楽 アニメ
posted by toshinagata at 17:52| 日記

2018年02月11日

セヴラック「ラングドックにて」

 1年前に買った「セヴラック・ピアノ作品集」を最近少しずつさらっている。

20180211-2.jpg

 音使いとしては、シャブリエのそれと少し通じるものがあるかな。下の譜例は「ラングドックにて」の第1曲「祭りの日の畑屋敷に向かって (Vers le Mas en fête)」より。赤で囲った小節、こういう音がよく出てくる。

20180211-1.png

 音楽は完全に描写的。同じく「ラングドックにて」の第3曲は「草原で馬に乗る (A cheval, dans la prairie)」で、こんな風に始まる。

20180211-3.png

 泉に着くとこうなる。6小節目はさっきと同じ和音。

20180211-4.png

 それで、また馬に乗って帰ってきて、最後はご丁寧に馬をうまやにつなぐところ(たぶん)まで描かれている。

20180211-5.png

 押し付けがましくない、素朴で明るい音楽です。あんまり DTM なんかには向いてない。気の向くままに、即興演奏っぽく自由に弾くのが合っている。

タグ:音楽
posted by toshinagata at 00:19| 日記
email.png
Powered by さくらのブログ