一往確認日記 |
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ファイルをダウンロードできます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
source "https://rubygems.org" | |
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } | |
gem "caxlsx" |
[ツッコミを入れる]