1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

シャトルランで流れる電子音をPythonで作成する

Last updated at Posted at 2022-09-11

はじめに

20メートルシャトルランとは一定時間、一定間隔で20m走り続ける体力測定の方法のひとつです。
最近の学校では持久走のかわりにこれをおこなっているようですが、私はやったことありません。
この測定時にタイミングを合わせるために電子音が流れますが、その電子音を作成します。
具体的にはシャトルランの楽譜を作ってみたのような音のようです。

方針

シャトルランでは1分間決められた速度で20m走を繰り返していきます。
そして1分間ごとにレベル(速度)が上がります。速度があがるのでレベル毎の走る回数も増えます。また、レベル毎に流れる電子音のBPMもあわせてあげる必要があります。
レベル毎の速度とBPMの関係は20mシャトルランの速さに記載の表のようになります。

電子音のデータはmusic21というライブラリを利用して作成します。
別途MuseScoreという楽譜作成ソフトのインストールが必要ですが、音楽には素人の私ような人間でも直感的なコードで簡単にMIDIデータや楽譜を作成してくれるとても便利なライブラリです。

コード

いきなりですが、全体コードです。

from music21 import *
import math

# レベル開始時のメロディ
def add_start(s):
    c = chord.Chord([note.Note('C5'),note.Note('C6')], quarterLength=0.25)
    s.append(c)
    c = chord.Chord([note.Note('G4'),note.Note('G5')], quarterLength=0.25)
    s.append(c)
    c = chord.Chord([note.Note('D5'),note.Note('D6')], quarterLength=0.5)
    s.append(c)

# 1走行中のメロディ
def add_run(s, is_up, is_end):

    # 音階の向き
    ns = [f'{c}4' for c in 'CDEFGAB'] + ['C5']
    if not is_up:
        ns.reverse()
    s.append([note.Note(n) for n in ns])

    # 最後以外は和音が入る
    if not is_end:
        c = chord.Chord([note.Note('C4'),note.Note('C3')])
        s.append(c)


s = stream.Stream()
s.append(meter.TimeSignature('9/4'))

st_cnt = 1   # 累積開始回
total_cnt = 0# 累積走行数
for i in range(19):

    # 走行速度 m/h
    if i == 0:
        v = 8000
    else:
        v = 9000 + 500*(i-1)

    # このレベルの回数
    loop_cnt = math.ceil( v/60 / 20) # 1min=60sec で20mを何回走れるか
    # ピッタリならさらに1回
    if divmod(v/60,20)[1] == 0:
        loop_cnt += 1

    ed_cnt = st_cnt + loop_cnt - 1 # 累積終了回
    bpm = 60 / 8000 * v
    print(f'Lv={i+1:2}, 回数={st_cnt:3}{ed_cnt:3}({loop_cnt:2}), BPM={bpm:6.2f}, 走行速度={v/1000:4.1f}')
    st_cnt = ed_cnt + 1

    # MIDIデータの作成
    s.append(tempo.MetronomeMark(number=bpm))
    add_start(s)
    for i in range(loop_cnt):
        add_run(s, total_cnt%2==0, i == (loop_cnt-1))
        total_cnt += 1

s.write('midi', 'run.mid')
print('show')
s.show()

ざっくり説明すると、まずはレベル毎に走行回数とBPMを計算して求めます。
次に、指定のBPMで走行回数分だけ電子音データを作成していきます。
最後にできたデータをMIDI形式で出力し、ついでに楽譜表示します。
temp.png

考察、その他

レベル開始時に流れる「ピロリ」というメロディや1走行終了後の和音の出現ルールが分からず苦労しました。楽譜をコードで書き出してはシャトルランの楽譜を作ってみたの楽譜と照らし合わせながらなんとかコード化できました。
完全に正しいかは分かりませんが、20メートルシャトルランに記載されている累積時間と出力MIDIの再生時間は一致しているので問題ないかと思います。

ちなみに60分(レベル19まで)続けると、走行距離は1162回x20m=23.24km、最終速度は37.5km/sとなるようです。

元ネタ:Python でシャトルランプログラムを作りたい!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?