音の標本化周波数と量子化ビット数を変えるプログラム

情報のディジタル化

こんにちは。前回は音の標本化周波数や量子化ビット数を変えてみて、その音の違いを聞くことができるような記事を書きました。

今回は、音の標本化周波数や量子化ビット数を変えるプログラムについて書きます。

音の標本化周波数や量子化ビット数を変えるプログラム

それでは早速プログラムを載せます。言語はPyhtonになります。

import wave
import struct
import numpy

# ファイルを読み出し
readf = 'read.wav'
wr = wave.open( readf, 'r' )

# waveファイルが持つ性質を取得
ch = wr.getnchannels()
width = wr.getsampwidth()
fr = wr.getframerate()
fn = wr.getnframes()
# waveの実データを取得し、数値化
data = wr.readframes( wr.getnframes() )
wr.close()

#readファイル関係のデータ表示
print( 'Read File :', readf )
print( '  Channel: ', ch )
print( '  Sample width: ', width )
print( '  Frame Rate: ', fr )
print( '  Frame num: ', fn )
print( '  Total time: ', fn/fr )


X = numpy.fromstring( data, dtype=numpy.int16 )

# 20秒分に相当するフレーム数を算出
time = 20
frames = int( ch * fr * time )

# 出力データを生成
#標本化周波数
frequency = 8000
#量子化マスク
mask = 0b1111111100000000

rate = fr // frequency
writef = 'write.wav'

Z = X[:frames:rate]
for i, d in enumerate(Z):
  Z[i] = Z[i] & mask
outd = struct.pack( "h" * len(Z), *Z )

#readファイル関係のデータ表示
print( 'Write File :', writef )
print( '  Channel: ', ch )
print( '  Sample width: ', width )
print( '  Frame Rate: ', fr//rate )
print( '  Frame num: ', frames//rate//ch )
print( '  Total time: ', len(Z) / (ch*fr//rate) )

# 書き出し
ww = wave.open( writef, 'w' )
ww.setnchannels( ch )
ww.setsampwidth( width )
ww.setframerate( fr//rate )
ww.writeframes( outd )
ww.close()

実行結果は次になります。

Read File : read.wav
  Channel:  2
  Sample width:  2
  Frame Rate:  44100
  Frame num:  6688512
  Total time:  151.6669387755102
Write File : write.wav
  Channel:  2
  Sample width:  2
  Frame Rate:  8820
  Frame num:  176400
  Total time:  20.0

簡単なプログラムの説明

24行目までで、ファイルの読み込み、音声のデータ形式を読み取る部分になります。getchannelsでチャンネル数(モノラル・ステレオ)を、getsampwidthで1サンプル当たりのバイト数(2byte=16bit)を、getframerateで標本化周波数を、getnframesで標本点の数を取得しています。

次に、主に音を加工している箇所を示します。

41行目で、先頭から20秒切り取り、さらに標本化周波数を変えています。元のデータの標本化周波数が44100Hzの場合、22050Hzに変える場合には単純にデータを1つおきに残すようにしています。11025Hzに変える場合には、連続した4つのうち1つだけデータを残すようにしています。

加工した音の標本化周波数を58行目のsetframerateで設定しています。ここで元の標本化周波数のままにしておくと、再生速度が上がってしまうことに注意が必要です。

次に量子化ビット数を変える部分です。データとして使っているビット数は16ビットのままですが、36行目の変数maskで加工後の音で有効にするビットを指定し、43行目で、元の音のデータと変数maskとのビットごとの論理積をとっています。これにより、元の音のデータのうち上位8bitだけが有効になり、量子化の際の段階数を減らすことができます。

sample widthが2byte(16bit)であると決め打ちしているので、プログラムとしての完成度は低いのですが、CD音源と同程度のデータを想定しているプログラムということで、ハイレゾ音源は対象外とさせてもらいたいな・・・と思っています。

今回は短いですが、これでおしまいにしたいと思います。それではまた。

Posted by 春日井 優