ssig33.com

音が鳴るエディタ軽量化

音の鳴るエディタが便利だけど使うと Vim が死ぬほど重くなる。適当に軽量化した。

~/bin/vim-key-sound.rb

#!/usr/bin/env ruby
open("#{ENV["HOME"]}/vim_audio_list",'a'){|x| x.puts ARGV[0]}

実際に音鳴らすやつ

#!/usr/bin/env ruby

require "coreaudio"
require 'kconv'

class SinWaveSounder
  LONG = 44000

  scale = 2.0 ** (1 / 12.0)
  FREQUENCIES = 28.times.map do |i|
    220 * (scale ** i)
  end

  def initialize
    dev = CoreAudio.default_output_device
    @buf = dev.output_loop(LONG)
  end

  def sound(frequency, sec)
    phase = Math::PI * 2.0 * frequency / LONG
    LONG.times do |i|
      @buf[i] = ((0.4 * Math.sin(phase*i)) * 0x7FFF).round
    end

    @buf.start
    sleep(sec)
    @buf.stop
  end

  def random_sound(seed, sec)
    i = seed.ord % FREQUENCIES.size
    sound(FREQUENCIES[i], sec)
  end
end

sounder = SinWaveSounder.new

while true
  f = open("#{ENV["HOME"]}/vim_audio_list")
  list = f.read.toutf8.split("\n")
  f.close
  list.delete_if{|x| x == ''}
  if list.count > 0
    f = open("#{ENV["HOME"]}/vim_audio_list", "w")
    f.puts ''
    f.close
    list.each{|x|
      next if x.nil? or x.empty?
      sounder.random_sound(x, 0.1)
    }
  end
  sleep 0.1
end

ちょっとした説明

Vim から呼ぶプロセスは入力されたものをキュー(と呼ぶのもおこがましい酷いもの)に溜め込むだけ。音は別のプロセスが鳴らす。まあ酷いもんだがこれでも実用的に動く。

実際に音を出すやつをターミナルとかで実行しておくと、音が出る。 vimproc で非同期にプロセス読んでも結局どこかでブロックしてるっぽい。呼び出すプロセスを軽くしたら軽くなった。もしかしたら中村さんが非同期にプロセス呼べてないだけかもしれないけど、僕も Vim 詳しくないのでよく分からない。

いずれにせよ上記のアプローチで実用的に音が出るようになった。非常にいいと思う。

back to index of texts


Site Search

Update History of this content