Subsections

基本的な定数などの計算・変換

音速

空気中の音速は、気温を$T$(℃)としたとき$331.5 + 0.6T$で計算できます。そのままプログラムにしたのが以下です。気温を指定しない場合は、東京の平均気温である16.3度を使用します。

def speed_of_sound(temperature=16.3):
    """Compute speed of sound in air from specified temperature
    (default value is 16.3 degrees (celcius), which is the average
    temperature in Tokyo)."""
    return(331.5 + 0.60 * temperature)

【使い方】気温20度のときの音速は?

speed_of_sound(20.0)   # -> 343.5
343.5 m/sでした。

周波数と音高にかかわるもの

MIDIセント値は、MIDIノート番号とそこからのずれを同時に扱うことができる便利な方法です。たとえば、中央のドはMIDIノート番号で60で、そこから15セント上のピッチは、60×100+15=6015と表せます。

def freq_to_midicent(freq, concert_pitch=440):
    """
    Convert frequency (Hz) to MIDI cent value (MIDI note number times
    100 for representing partial pitch).
    """
    midicent = np.log2(freq / concert_pitch) * 1200 + 6900
    return(midicent)

def midicent_to_freq(midicent, concert_pitch=440):
    """
    Convert MIDI cent value (MIDI note number times 100 for
    representing partial pitch) to frequency (Hz).
    """
    freq = concert_pitch * 2**((midicent - 6900) / 1200)
    return(freq)

【使い方】コンサートピッチが442 Hzのとき、ピアノ鍵盤上で1000 Hzはどのあたり?

freq_to_midicent(1000, 442)   # -> 8313.4580703247866
MIDIノート番号で83番付近。ピッタリより若干(13.458セント)上。

音圧と振幅にかかわるもの

def db_to_amplitude(db_value, base=1.0):
    """
    Calculate amplitude value from dB value.
    """
    return(10**(db_value / 20) * base)

def amplitude_to_db(amp_value, base=1.0):
    """
    Calculate dB value from amplitude value.
    """
    return(20*math.log10(amp_value / base))

def db_to_power(db_value, base=1.0):
    """
    Calculate power value from dB value.
    """
    return(10**(db_value / 10) * base)

def power_to_db(pow_value, base=1.0):
    """
    Calculate dB value from power value.
    """
    return(10*math.log10(pow_value / base))

def rms(x):
    """
    Calculate signal RMS.
    """
    return(scipy.sqrt(sum(x**2) / len(x)))

def rms_moving(x, window_size=8192, hop_size=1024):
    """
    Calculate RMS of a signal as in moving average.
    Usage:
        x, samprate = soundfile.read("audio.wav")
        r, t = rms_moving(x, samprate, window_size=8192, hop_size=1024)
        matplotlib.pyplot.plot(t, r)
    """
    num_frames = (len(x) + window_size-1) // hop_size
    xx = np.hstack((x, np.zeros(2 * window_size)))
    rmss = np.zeros(num_frames)
    for n in range(num_frames):
        xxx = xx[hop_size*n : hop_size*n+window_size-1]
        rmss[n] = rms(xxx)
    t = np.arange(num_frames) * hop_size
    return(rmss, t)

def crest_factor(x):
    return(np.max(np.abs(x)) / rms(x))

時間にかかわるもの

def time_to_samples(sec, samprate=44100):
    """
    Convert time (in seconds) to number of samples.
    """
    return(sec * samprate)

def samples_to_time(samples, samprate=44100):
    """
    Convert number of samples to time (in seconds).
    """
    return(samples / samprate)

その他

def nextpow2(val):
    """
    Returns 2**n value that is the smallest among the larger 2**n's
    """
    return(int(math.pow(2, math.ceil(np.log2(val)))))



MARUI Atsushi
2025-04-15