空気中の音速は、気温を(℃)としたとき
で計算できます。そのままプログラムにしたのが以下です。気温を指定しない場合は、東京の平均気温である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.5343.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.4580703247866MIDIノート番号で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)))))