«前の日記(2020年11月20日) 最新 次の日記(2020年11月29日)» 編集

一往確認日記


2020年11月22日 [長年日記]

_ ENVELOPE - その3

前回のENVELOPE - その2の続きです。

何回も出てますが、このコマンドでどの様な音程になるかグラフにしてみます。

ENVELOPE 2,1,2,-2,2,10,20,10,1,0,0,-1,100,100
SOUND 1,2,100,100

caxlsxを使うとRubyからExcelファイルを生成することができます。グラフも書かせることができて便利です。

こちらが生成したグラフです。
青色が音程で、80(G2)から120(F3)まで周期的に上下しています。
オレンジ色は音量の変化になります。

音程グラフ

こちらがRuby srciptになります。 27、28行目のENVELOPE、SOUNDコマンドを書き換えると他のパターンも試すことができます。
envelope.xlsxの右端のview rawを押すとExcelファイルをダウンロードできます。

require 'caxlsx'
# envelope's parameter no
ENV_N = 0
ENV_T = 1
ENV_PI1 = 2
ENV_PI2 = 3
ENV_PI3 = 4
ENV_PN1 = 5
ENV_PN2 = 6
ENV_PN3 = 7
ENV_AA = 8
ENV_AD = 9
ENV_AS = 10
ENV_AR = 11
ENV_ALA = 12
ENV_ALD = 13
# sound's parameter no
SND_C = 0
SND_A = 1
SND_P = 2
SND_D = 3
# commands
lines =<<EOS
ENVELOPE 2,1,2,-2,2,10,20,10,1,0,0,-1,100,100
SOUND 1,2,100,100
EOS
# divide commands to parameters
lines.each_line do |l|
case l.scan(/\w+/).first.upcase
when "ENVELOPE"
@envelope = l.scan(/\-?\d+/).to_a.map(&:to_i)
when "SOUND"
@sound = l.scan(/\-?\d+/).to_a.map(&:to_i)
end
end
# pitch pattern
@pitch = [@sound[SND_P]]
[
[ENV_PI1, ENV_PN1],
[ENV_PI2, ENV_PN2],
[ENV_PI3, ENV_PN3],
].each do |pi,ni|
@envelope[ni].times do
@pitch << @pitch.last + @envelope[pi]
end
end
# make envelope of amplitued
@duration = @sound[SND_D] / 20.0
@time = 0
@t_delta = @envelope[ENV_T] / 100.0
@amplitude = [0]
while @time < @duration && @amplitude.last < @envelope[ENV_ALA]
@amplitude << [@amplitude.last + @envelope[ENV_AA], @envelope[ENV_ALA]].min
@time += @t_delta
end
while @time < @duration && @amplitude.last > @envelope[ENV_ALD]
@amplitude << [@amplitude.last + @envelope[ENV_AD], 0].max
@time += @t_delta
end
while @time < @duration
@amplitude << [@amplitude.last + @envelope[ENV_AS], 0].max
@time += @t_delta
end
while @amplitude.last > 0 && @envelope[ENV_AR] < 0
@amplitude << [@amplitude.last + @envelope[ENV_AR], 0].max
@time += @t_delta
end
# generate excel file
p = Axlsx::Package.new
p.workbook.add_worksheet(:name => "Pitch") do |sheet|
sheet.add_row ["ENVELOPE"] + @envelope
sheet.add_row ["SOUND"] + @sound
sheet.add_row []
sheet.add_row ["TIME", "PITCH", "AMPLITUDE"]
# fill data cells
c = @amplitude.size
cp = @pitch.size
@time = 0
c.times do |i|
sheet.add_row [@time, @pitch[i % cp], @amplitude[i]]
@time += @t_delta
end
# add chard
sheet.add_chart(Axlsx::ScatterChart, title: "PITCH & AMPLITUDE", start_at: 'E5', end_at: 'R25') do |chart|
chart.add_series xData: sheet["A5:A#{(5 - 1) + c}"], yData: sheet["B5:B#{(5 - 1) + c}"], title: sheet['B4']
chart.add_series xData: sheet["A5:A#{(5 - 1) + c}"], yData: sheet["C5:C#{(5 - 1) + c}"], title: sheet['C4']
end
end
p.use_shared_strings = true
p.serialize('envelope.xlsx')
view raw envelope.rb hosted with ❤ by GitHub
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "caxlsx"
view raw Gemfile hosted with ❤ by GitHub