Pythonで三角関数!〜サウンドも作成してみよう数学×Pythonプログラミング入門(4/4 ページ)

» 2022年11月28日 05時00分 公開
[羽山博]
前のページへ 1|2|3|4       

練習問題

 では、練習問題です。問題の考え方について解説した動画も用意してあります。ぜひご視聴ください。

動画4 三角関数の練習問題


(1)2つのベクトルの成す角のcosθの値を求める

 ベクトルaとベクトルbの内積abは以下の式で求めることができます。

 ただし、abも零(ゼロ)ベクトルではないものとします。

 この式を使って、abのなす角度θに対するcosθの値を求めてみてください。例えば、a=(1,3,4)b=(2,−1,3)の場合は、cosθ=0.576..となります。

(2)sin関数を使ってサウンド(「ラ」の音)を作る

 440Hz(ヘルツ)の正弦波で表される「ラ」の音を作成する関数makesoundを作成し、作成したサウンドデータをWAVファイルとして保存してみましょう。

 440Hzの正弦波とは、図9の赤い色で示したように、0までの波が1秒間に440回繰り返されるようなsin関数の波のことです。振幅(波の高さ)は1とし、32ビットの浮動小数点数として表すものとします。

440Hzの正弦波 図9 440Hzの正弦波
Hzは単位時間(1秒)当たりの周期の数。この例では赤い矢印で示されている部分が1周期で、それらが1秒間に440個あるので440Hzとなる。このような波の高さ(青い線と○で表されている)を求めることを量子化と呼ぶ。この例では、1秒間を44100個に分けて量子化している。

 波の高さを数値として表すことを量子化と呼びます。また、短い時間間隔で区切って量子化された値を順に取り出すことをサンプリング標本化)と呼びます。サウンドデータはこのようにして作られるというわけです。ここでは、1秒当たり44100回のサンプリングを行うことにします。図9の青い色で示したようなイメージです*3


注3

*3 1秒当たりのサンプリングの回数のことをサンプリング周波数と呼びます(同じHzという単位を使いますが、正弦波そのものの周波数とは異なります)。ちなみに、CDでは、量子化ビット数が16、サンプリング周波数が44100Hzで、左右の音が別々に(ステレオで)記録されています。


 サンプリングしたデータを保存すればWAVファイル(拡張子:.wav)が作成できます。以下のリスト7の関数makesoundを完成させてください。関数makesoundの引数には、作成したい正弦波の周波数、持続時間、サンプリング周波数を指定するものとします。

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

def makesound(freq, duration, rate):
  # この内容を書く
  # 作成したデータはsampleという名前の配列に記録するものとする
  return sample.astype(np.float32)

freq = 440
duration = 1
rate = 44100
sample = makesound(freq, duration, rate)

# サウンドを保存する
wavfile.write('sample.wav', rate, sample)
print(max(sample), min(sample))  # 振幅が適切かどうかを確認しておく

# 一部だけグラフを表示
plt.plot(sample)
plt.axis([0, 400, -1.0, 1.0])
plt.show()

リスト7 サウンド(「ラ」の音)を作る(未完成)
関数makesoundの内容を書いてコードを完成させ、サウンドデータを表す配列を作成しよう。.wavファイルに保存するにはscipy.ioモジュールのwevfile.write関数を利用する。そのためのコードはすでに書かれているので引数にファイル名、サンプリング周波数、サウンドデータを指定すればよい。振幅(音量)が適切かどうかを確認するために、print関数によりサウンドデータの最大値と最小値を表示してある(後述)。

 サウンドデータの作成方法は、目標3で取り扱った例と考え方は全く同じです。目標3の最後の例では、周波数が3の正弦波を作成し、1秒間に100回のサンプリングを行っていたものと考えられます。また、持続時間をdurationで指定していることにも注意してください。

 コードを完成させて実行すると、sample.wavという名前のファイルが作成されます。図10に示した方法でダウンロードし、再生してみましょう。ただし、間違ったコードを書くと、耳障りな音になったり、大音量で再生されたりしてスピーカーにダメージを与える可能性があるので、十分に注意してください。sampleの値が全て-1.01.0の範囲に収まっていれば、音量に関しては問題ありませんが、最初はできるだけボリュームを絞って再生してください*4


注4

*4 ここでは、32ビット浮動小数点数のサウンドデータを作成しましたが、wavfile.write関数では、8ビット符号付き整数16ビット符号付き整数32ビット符号付き整数のいずれでもサウンドデータの作成ができます。例えば、上記の*3で触れたCDのサウンドデータは16ビット符号付き整数なので、astype(np.int16)を指定し、-3276832767の範囲の整数として保存する必要があります。しかし、それらのデータを間違って浮動小数点数として保存すると、-1.01.0を大きく逸脱した値になるので、とてつもなく大きな音量で再生されてしまいます。


サウンドの作成例 図10 作成されたサウンドとダウンロードの方法
完成したコードを実行すると、サウンドデータが作成され、振幅の最大値と最小値が表示される。また、サンプリングしたデータのうち先頭から400個分を基に波形が描かれる。作成したサウンドデータをダウンロードするには、Google Colabの左側に表示されているフォルダの形のアイコンをクリックして、フォルダー一覧を表示し、[sample.wav]を右クリックして[ダウンロード]を選択すればよい。

 ダウンロードしたsample.wavファイルは、WindowsでもmacOSでも、通常[ダウンロード]フォルダーに保存されます。エクスプローラーやFinderを開いてsample.wavファイルをダブルクリックすると再生ができます。

 作成した「ラ」の音は、以下のような平板な音になるはずです(音が大きめなので、音量は小さくして再生してください)。

 これは単純なsin関数の波形(純音)だからです。実際の楽器では、倍音(基本となる周波数の何倍かの周波数の音)が含まれていたり、それらの減衰速度が異なったりすることにより、楽器独特の音色が生み出されます。次の練習問題では、実際の楽器の波形を描いてみます。

(3)WAVファイルを読み込んで情報や波形を表示する

 実際のサウンドを読み込んで、その情報や波形を描画してみましょう。例えば、以下の音は電子ピアノ(Korg C1 Air)で弾いたラ(A4)の音で、最初に無音部分があり、徐々に減衰していきます。このサウンドの波形を描くことにしましょう。

 以下のコード(リスト8とリスト9)は、上記のサウンドファイル(.wavファイル)を取得し、サウンドデータを読み込むためのものです。このコードに続けて、サンプリング周波数、データのタイプ(量子化ビット数)、チャンネル数(モノラルかステレオか)、持続時間を表示するとともに、波形を描画してみてください。ただし、データ量が多いので、振幅が最大である位置から400個のサンプルを抽出してプロットすることにしましょう。横軸と縦軸の目盛は特に指定しなくても構いません。

# WAVファイルをGoogle Colabにダウンロードする(1回実行しておけばよい)
!wget "https://raw.githubusercontent.com/Gessys/math/main/data/la.wav"

リスト8 WAVファイルをGoogle Colabにダウンロードするコード
!wgetはJupyterノートブック(Google Colabはその互換環境)のマジックコマンドと呼ばれる機能を活用したもので、外部ファイルを取得するために使う。取得した“la.wav”という名前のファイルがGoogle Colabで使えるようになる。

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

# WAVファイルを読み込む
rate, data = wavfile.read('la.wav')
# サンプリング周波数、データのタイプ、チャンネル数、持続時間を表示するための
# コードをここに書く

# 波形のグラフを描くコードをここに書く

リスト9 WAVファイルの情報を表示し波形を描くコード(未完成)
scipy.ioモジュールのwavfile.read関数を使い、リスト8でダウンロードしたサウンドデータを読み込む。返り値はサンプリング周波数とサウンドデータ。それらを使ってWAVファイルの情報を表示し、波形を描くとよい。

 実行例は図11の通りです。

WAVファイルの波形を描く 図11 電子ピアノのラ音の波形
実際の楽器では、ラ音を表す440Hzの波に加えて幾つかの倍音が含まれているので、このような形になる。サンプリング周波数が44100Hzなので、44100/440 ≈ 100個のサンプルで1周期となる。グラフには、ほぼ4周期分の波が表示される。

 図11を見ただけではどのような周波数の波が含まれているかは分かりませんが、離散フーリエ変換と呼ばれる手法を利用すれば、波に含まれる周波数の成分を求めることができます。これについては、練習問題(3)の作成例の後で、発展的な話題として(簡単にですが)紹介することにします。

練習問題の解答例

 以下、解答とプログラムの作成例です。もちろん、異なるやり方もあるので、これらが唯一の答えというわけではありません。

(1)2つのベクトルの成す角のcosθの値を求める

 これは、以下の式を変形すれば簡単です。abも零ベクトルではないので、|a||b|も正の値となります。従って、両辺を|a||b|で割れば、

は、

となります。

なので、(1)式をそのままコードとして表すだけでできます(リスト10)。

import numpy as np

a = np.array([1, 3, 4])
b = np.array([2, -1, 3])

print(a@b / np.sqrt(a@a * b@b))
# 出力例:
# 0.5765566601970551

リスト10 cosθの値を求めるコード
ベクトルaの長さ|a|は、自分自身との内積を求め、そのを取れば求められる。np.linalg.norm(a, 2)と書いて、L2ノルムを求めてもよい。なお、その部分をa**2とすると、aの各要素を2乗したベクトルを求めることになるので、正しい答えが得られない。

 (1)式の分母は、

ですが、全体にをかけて、

と表すこともできます。リスト10の作成例では(2)式で分母を求めています(細かいことですが、sqrt関数の呼び出しが1回で済みます)。

コラム 相関係数はcosθそのもの

 さまざまなデータの並びはn次元のベクトルとして表すことができます。例えば、気温ならx={12, 15, 24, 38, 27, 32}のように表せます。気温のそれぞれの値に対応するビールの出荷数(ケース単位)ならy={5, 8, 14, 57, 33, 48}といった具合です。これらは一般的に、x={x1, x2, ... xn}や、y={y1, y2, ... yn}と表すことができます。ここで、各要素から平均値

を引いて作成したベクトル

を考えてみましょう。これらは、原点を

に移動した場合のxyと考えられます。このとき、XYのなす角度θに対するcosθの値は、

となります。

 この式をどこかで見たことがないでしょうか。この式は相関係数を表す式にほかなりません。相関係数の正体はcosθだったのです。

  • XYが同じ向きの場合は、角度θ0なので、cosθの値は1(正の相関)
  • XYが直交している場合は、角度θπ/4なので、cosθの値は0(無相関)
  • XYが逆の向きの場合は、角度θπ/2なので、cosθの値は-1(負の相関)

 このことから、相関係数はベクトルがどれぐらい同じ向きを向いているかということだという図形的なイメージがつかめると思います。また、相関係数が-11の値を取ることも納得できると思います。


(2)sin関数を使ってサウンド(「ラ」の音)を作る

 以下のパターンに、サウンドの周波数freq、持続時間duration、サンプリング周波数rateを当てはめるだけで、サウンドデータが作成できます。以下の手順通りにコードを書けばどのような正弦波も必ず作成できますが、意味を理解することが重要なので、コードの後に図解も掲載しておきます。

  • [1]必要なデータの数を求める: サンプリング周波数と持続時間の積で求められる
  • [2]numpyモジュールのlinspaceを使い、0から持続時間までをデータの数で刻んだ等差数列tを作る
  • [3]numpyモジュールのsin関数の引数に2*np.pi * freq * tを指定する
  • [4]振幅を変えたければ[3]に振幅ampを掛ける(ここでは振幅が1.0なので不要)

 以下の例では、サウンドデータは-1.01.0の範囲の浮動小数点数として表されます。

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

def makesound(freq, duration, rate):
  n = rate * duration  # データ数
  t = np.linspace(0, duration, n)  # 持続時間をデータ数で区切る
  sample = np.sin(2*np.pi * freq * t)
  return sample.astype(np.float32)

freq = 440
duration = 1
rate = 44100
sample = makesound(freq, duration, rate)

# サウンドを保存する
wavfile.write('sample.wav', rate, sample)
print(max(sample), min(sample))  # 振幅が適切かどうかを確認しておく

# 一部だけグラフを表示
plt.plot(sample)
plt.axis([0, 400, -1.0, 1.0])
plt.show()

リスト11 WAVファイルを作成するためのコード
関数makesoundは、目標3で見たコードと全く同じ考え方。サウンドの周波数freqの値と、サンプリング周波数rateの値が異なるだけ。目標3の例では持続時間が1秒だったが、ここでは持続時間をdurationとして指定している。以下の図解も参照するとよい。実行例は図10で見た通り。

 図12で考え方をいま一度確認しておきましょう。

  • サンプリング周波数がrateであるとすると、1秒間にrate個のデータを取り出す(量子化する)ことになる
  • サウンドがduration秒の長さであるとすれば、全体のデータの個数nrate × duration
  • 刻み幅1/raten個のサンプルを取り出す
サウンド作成のパターン 図12 サウンドを作成する上での考え方
サウンドデータを作るための基本的なパターン。tの値を1/rateずつ増やしながら、duration秒まで、周波数freqの正弦波をサンプリングしていく。リスト11はこの図に示したサンプリングの方法をコードとして表したものになっている。

 リスト11のt = np.linspace(0, duration, n)というコードに注目してください。durationn=rate × duration個に分けるということなので、刻み幅はduration/(rate × duration)=1/rateとなります。つまり、t1/rate刻みでdurationまで増やしていくということです。sample = np.sin(2*np.pi * freq * t)いうコードで正弦波が作れますが、これは目標3のコードそのままです。

 ここでは、サウンドを32ビット浮動小数点数として表しているので振幅は1.0ですが、16ビット符号付き整数で表すのであれば、値の範囲が-3276832367なので、sin関数の値に32767を掛けて、振幅を32767までとします。

def makesound16(freq, duration, rate):
  n = rate * duration  # データ数
  t = np.linspace(0, duration, n)  # 持続時間をデータ数で区切る
  amp = 32767  # 16ビット符号付き整数の最大値
  sample = np.sin(2*np.pi * freq * t) * amp
  return sample.astype(np.int16)  # 必ずデータ型を合わせておくこと

リスト12 16ビット符号付き整数でWAVファイルを作成するための関数
しつこいようだが、必ず、astypeメソッドを使ってデータ型を16ビット符号付き整数にしておくこと。浮動小数点数のまま保存すると、スピーカーや耳にダメージを与えるような大音量でサウンドが再生されてしまう。

(3)WAVファイルを読み込んで情報や波形を表示する

 WAVファイルを読み込むためのコードはすでに書かれており、rateでサンプリング周波数が、dataでサウンドデータが参照できるようになっているので、以下の値を求めれば必要な情報が表示できます。

  • サンプリング周波数: rateの値
  • データのタイプ: datadtype属性
  • チャンネル数: dataの次元数
  • 持続時間: データの長さ÷サンプリング周波数の値

 また、振幅の最大値がどの位置にあるかは、numpyモジュールのargmax関数を使って、配列の中の最大値のインデックスを求めれば分かります。その位置から400個分のデータを取り出して波形を描画すればコードの完成です。matplotlib.pyplotモジュールのplot関数を使って折れ線グラフを描くだけです。

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

# WAVファイルを読み込む
rate, data = wavfile.read('la.wav')
print('サンプリング周波数:', rate)
print('データのタイプ:', data.dtype)
print('チャンネル数:', data.ndim)
print('持続時間:', len(data) / rate)

# グラフを描画する
start = np.argmax(data) # 振幅が最大となる位置
end = start + 400
sample = data[start:end]
plt.plot(sample)
plt.show()

リスト13 WAVファイルの情報を表示し波形を描くコード
読み込まれたデータ(data)はnumpyの配列になっているので、dtype属性を取得すればサウンドデータのタイプが分かる。またndim属性で次元の数を求めればチャンネル数が分かる。numpyモジュールのargmax関数を使って、配列の最大値のインデックスを求めれば、最大の振幅の位置も分かる。そこから400個分の値をプロットすれば波形が描ける。実行例は図11ですでに見た通り。

 サウンドデータを読み込んで波形を表示するだけであれば簡単ですね。ただ、サウンドを解析したり、サウンドを合成したりするためには、サウンドに含まれる周波数成分を調べるなど、さまざまな処理の方法を知る必要があります。ここでは、ほんの入り口だけしか紹介できませんが、以下、発展的な話題として、ハニング窓によって分析する範囲を取り出す方法と、離散フーリエ変換によって周波数成分を取り出す方法を紹介します。サウンドの解析やサウンドプログラミングについては『Excelで学ぶフーリエ変換』(小川智哉監修、渋谷道夫・渡邊八一著、オーム社)『Pythonではじめる音のプログラミング』(青木直史著、オーム社)などが詳しいので、興味のある方はご参照ください。

応用発展: 離散フーリエ変換により周波数成分を取り出す

 サウンドデータにどの周波数の波が含まれているかを調べるには離散フーリエ変換と呼ばれる方法を使います。この連載の第4回の練習問題でフーリエ級数を利用して矩形波を描画する例を紹介しましたが、離散フーリエ変換は、その逆の計算を行うものと考えられます。

 まず、離散フーリエ変換を行うための準備として、サウンドデータのうち、分析の対象とする部分を取り出す関数を作っておきましょう。そのような関数は、全てのデータの一部分を「窓」から覗(のぞ)くようなイメージなので、窓関数と呼ばれます。

 上の練習問題では、一定の範囲をそのまま取り出しましたが、それが最もシンプルな「窓」です。その場合、四角い窓から見える部分だけを取り出しているようなイメージなので「方形窓」と呼ばれます(図13の左)。

 しかし、方形窓では、開始位置と終了位置の波の高さが異なるので、取り出した波が繰り返すものとすると、その位置にギャップができてしまい、分析の精度が下がってしまいます。そのため、開始位置と終了位置がスムーズにつながるように、両端の振幅を小さくするような窓関数を使って分析のためのデータを取り出すのが一般的です。ここでは、さまざまな窓関数のうち、よく使われているハニング窓ハン窓)関数を作成してみます。図13の右がハニング窓を適用した例です。

方形窓とハニング窓 図13 方形窓とハニング窓
方形窓の場合はサウンドデータの一部分をそのまま取り出すので、開始位置と終了位置の高さが異なっている。ハニング窓を適用すると、開始位置と終了位置が一致する。それぞれの窓で周波数成分を取りだした場合の違いについては後述する(図14)。

 ハニング窓関数は、以下の式で表されます。nは取り出すデータの個数です。

 取り出したデータの値にこの式の値をそれぞれ掛ければ、分析に使うデータが作成できます。が、その前にハニング窓関数の作成と動作確認をしておきます(リスト14)。

def hanning(n, sym=True):
  x = np.linspace(0, 1, n, endpoint=sym)
  return 0.5 - 0.5 * np.cos(2*np.pi * x)

# 動作確認のためのコード
print(hanning(6, True))
print(hanning(6, False))
# 出力例:
# [0.        0.3454915 0.9045085 0.9045085 0.3454915 0.       ]  # 左右対称の値になっている
# [0.   0.25 0.75 1.   0.75 0.25]  # 左右対称になっていない

リスト14 ハニング窓を作成する関数のコード
窓を左右対称にするかどうかを引数symで指定できるようにした。numpyモジュールのlinspace関数を使って01n個に刻んで窓関数の値を求めていく。窓を左右対称にする場合は、引数endpointの値がTrueとなるので、末尾を含めて窓の範囲を分割し、値を求める。対称にしない場合は末尾を含まずに窓の範囲を分割することになる。通常は左右対称にするのでTrueを指定すればよい。いずれの場合も中心付近に比べて両端が小さな値になっていることが分かる。

 実はハニング窓を作るための関数としては、numpyモジュールのhanningという関数が利用できます。numpyモジュールのhanning関数では引数にデータ数のみを指定します。その場合、リスト14で作成したhanning関数にsym=Trueを指定した結果と同じになります。ちなみに、scipy.signal.windowsモジュールにもhann関数があり、そちらはリスト14で作成したhanning関数と同じ働きになります(sym=Trueが既定値となっていますが、sym=Falseの指定もできます)。

 分析対象の部分に窓関数を適用したデータを作成し、numpy.fftモジュールのfft関数により離散フーリエ変換を行えば、周波数成分が取り出せます。つまり、波形を表すデータ(縦軸が振幅、横軸が時間)を、周波数を表すデータ(縦軸が振幅、横軸が周波数)に変換できるというわけです。このとき、得られる値(振幅)は複素数の形になっているので、その周波数成分の大きさを得るには、複素数の絶対値を求める必要があります*5。ただし、そのままでは値が大きくなるので、n/2で割った値の絶対値を求めて振幅の値とします。横軸となる周波数の配列は自分で作成することもできますが、numpy.fftモジュールのfffreq関数を使えば簡単に作れます。これらの値をプロットすれば、周波数成分が可視化できるというわけです。


注5

*5 離散フーリエ変換によって求められた値は、各周波数成分に対する複素数平面上の円の半径、つまり振幅を複素数で表したものとなっています。図8で見た複素数平面上の円の半径に当たります(図8では半径=1でした)。


 練習問題(3)で見た、電子ピアノの「ラ」の音を例として、コード全体と実行結果を示しておきます(リスト15〜16、図14)。分析対象の範囲は振幅が最大の位置から2048個のデータとします。

# WAVファイルをGoogle Colabにダウンロードする(1回実行しておけばよい)
!wget "https://raw.githubusercontent.com/Gessys/math/main/data/la.wav"

リスト15 WAVファイルをGoogle Colabにダウンロードするコード
リスト8で見た通り、これは1回だけ実行しておけばよい(すでに実行していれば、このコードの実行は不要)。

import numpy as np
from scipy.io import wavfile
import matplotlib.pyplot as plt

# ハニング窓関数
def hanning(n, sym=True):
  x = np.linspace(0, 1, n, endpoint=sym)
  return 0.5 - 0.5 * np.cos(2*np.pi * x)

# WAVファイルを読み込む
rate, data = wavfile.read('la.wav')

# 分析対象の範囲
start = np.argmax(data)
end = start + 2048
sample = data[start:end]

# ハニング窓を適用
n = len(sample)
w = hanning(n)
sample = (sample * w).astype(np.int16)

# 離散フーリエ変換により、周波数成分を表示する
sp = np.fft.fft(sample)
amp = np.abs(sp/(n/2))   # 振幅の配列(縦軸の値)
f = np.fft.fftfreq(n, d=1# 周波数の配列(横軸の値)
plt.plot(f[1: n//2], amp[1: n//2])
plt.xlabel("Freqency")
plt.ylabel("Amplitude")
plt.axis([0, 5000, 0, 2500])   # 主要な部分だけグラフ化
plt.show()

リスト16 離散フーリエ変換により周波数成分を表示するコード
離散フーリエ変換を行うには、窓関数により取り出したサンプルをnumpy.fftモジュールのfft関数に指定するだけでよい。得られた値(振幅)は複素数で表されており、大きな値になっているので、n/2で割ってから絶対値を求める。横軸はnumpy.fftモジュールのfftfreq関数で求める。n個のデータを、引数dで指定した幅で区切った場合の刻み値を基に、周波数を表す配列を作成しているだけ。周波数の半分までをプロットしている理由は後述。

ハニング窓と方形窓 図14 リスト16の実行結果(左:ハニング窓、右:方形窓)
リスト16をそのまま実行すると、左のハニング窓を適用した場合のグラフが描かれる。sample = (sample * w).astype(np.int16)をコメントアウトして実行すると右の方形窓の場合のグラフとなる。方形窓の場合、ピークとなる周波数の周囲の裾が広がる(そのため、この部分をスカートと呼ぶこともある)。なお、ハニング窓を適用すると、図13で見たように左右の値が小さくなるので、振幅は元の値よりも小さく表示される。440Hz880Hz1320Hz1760Hzなどの周波数成分があることが分かる。

 実行結果を見ると、ラ音を表す440Hzの周波数のほか、倍音の880Hzや3倍音の1320Hz、4倍音の1760Hzなどの周波数成分が含まれていることが分かります。このような周波数の特性や各成分の減衰時間などを基に、サウンドを合成することもできるというわけです。

 プロットする周波数の上限をサンプリング周波数の半分までとしているのは、サウンドを再現するためにはサウンドに含まれる周波数の倍以上の周波数でサンプリングする必要があるからです。それよりもサンプリング周波数が小さいと、うまく元の音が再現できません。サンプリング周波数の半分の周波数をナイキスト周波数と呼びますが、ナイキスト周波数よりも高い周波数のサウンドが含まれていると、正しくサンプリングができないということです。逆に言うと、22050Hzまでの周波数が含まれているサウンドであれば、44100Hzの周波数でサンプリングすれば元の音が再現できることになります。ここでは、元のサウンドに22050Hz以上の周波数が含まれていないという前提でサンプリングを行っているので、44100Hzの半分までをプロットしているわけです(ちなみに、CDなどでは22050Hz以上の周波数はカットされて収録されています。人間の可聴域が約20000Hzまでと言われているので、聞こえる音は22050Hzまでで十分に再現できるというのがその理由です)。


 ……というわけで、今回は、三角関数の基本の基本から、サウンドデータの作成や分析について紹介しました。AI/機械学習においても、サウンドデータを取り扱うことがあります。そのための初めの一歩といった感じです。サウンドデータの取り扱いを理解するにはグラフによる可視化が大いに役立ちます。

 次回は、機械学習に必要不可欠な大量データの取り扱いと記述統計について一通り整理し、応用例として回帰や分類の例も紹介したいと思います。

「数学×Pythonプログラミング入門」のインデックス

数学×Pythonプログラミング入門

前のページへ 1|2|3|4       

Copyright© Digital Advantage Corp. All Rights Reserved.

アイティメディアからのお知らせ

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2026
人に頼れない今こそ、本音で語るセキュリティ「モダナイズ」
4AI by @IT - AIを作り、動かし、守り、生かす
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。