メモ

メモ、雑記、etc

piano roll with python (1-3)

2010-12-25 23:11:30 | programming python

試しにピアノロール出力した画像を張り付けました。


# def draw_pianoroll(filename):の続き

        # FFTとマップ書き込み
        fin_pos = fin.tell()
        nloop = 0
        maxdb = -99.0
        remain = _nframes
        while remain > 0:
            # FFT
            bufsize = min(wav_chunk, remain)
            rowdata = fin.readframes(bufsize)
            arydata = scipy.fromstring(rowdata, dtype)
            if _channel == 2:   # stereo -> mono
                left  = scipy.int32(arydata[::2])
                right = scipy.int32(arydata[1::2])
                arydata = scipy.int16((left + right) / 2)
            len_ary = len(arydata)
            narydata = arydata / 2.0 / (2 ** 15)
            fftdata = scipy.fft(narydata)
            # power spectrum
            len_real = int(math.ceil((len_ary + 1) / 2.0))
            fftdata = fftdata[0:len_real]
            fftdata = fftdata * 2.0 / len_ary   # len_realではないことに注意
            fftdata = fftdata ** 2
            pw = 10 * scipy.log10(fftdata)
            remain -= bufsize
           
            # マップ書き込み
            cur_pos = img_start + int(nloop * cur_linerate + 0.5)
            for pwcnt in range(dis_min, min(dis_max, len_real)):
                if mod_fine:
                    if pos_cent[pwcnt] > 0 and cur_pos > 0 and cur_pos < img_height:
                        _check = db2pix(pw[pwcnt])
                        if img_max.getpixel((pos_cent[pwcnt], cur_pos)) < _check:
                            draw_max.point((pos_cent[pwcnt], cur_pos), fill=_check)
                            if pw[pwcnt] > wav_db:
                                color_base_idx = min(color_size-1, int( ((pw[pwcnt] - wav_db)) / (wav_db_max - wav_db) * color_size) )
                                draw.ellipse((pos_cent[pwcnt]-1, cur_pos-1, pos_cent[pwcnt]+1, cur_pos+1), fill=color_base[color_base_idx])
                else:
                    if pw[pwcnt] > wav_db and pos_cent[pwcnt] > 0:
                        color_base_idx = min(color_size-1, int( ((pw[pwcnt] - wav_db)) / (wav_db_max - wav_db) * color_size) )
                        draw.ellipse((pos_cent[pwcnt]-1, cur_pos-1, pos_cent[pwcnt]+1, cur_pos+1), fill=color_base[color_base_idx])
            if cur_pos >= img_height:
                break
            nloop += 1
           
            maxdb = max(maxdb, max(pw))
            if nloop % 50 == 0: print ' ' + str('%.0f' % maxdb),; maxdb = -99.0
       
        # ファイルポインタを戻す
        fin.setpos(fin_pos)
        print '.'
   
    fin.close()
   
    print 'pass %d [s]' % (wav_chunk / float(_framerate) * (nloop - 1))
    image.rotate(90).show()
    if mod_fine: img_max.rotate(90).show()

if __name__ == '__main__':
    if len(sys.argv) < 1:
        print 'Usage: %s ' % sys.argv[0]
        sys.exit(1)

    filename = '/tmp/track04.cdda.wav'
    if len(sys.argv) > 1:
        filename = sys.argv[1]
   
    draw_pianoroll(filename)

サンプル画像

ベース系は空間分解能がいまいちですね。 Waveletとかの方が良さそうですが、自力で書く能力はない…。



最新の画像もっと見る

コメントを投稿